package com.laytonsmith.core.constructs;
import com.laytonsmith.PureUtilities.Version;
import com.laytonsmith.annotations.typeof;
import com.laytonsmith.core.CHVersion;
import java.util.concurrent.atomic.AtomicLong;
/**
* A resource is a large or mutable data structure that is kept in memory with
* external resource management. This makes certain things more efficient, like
* string builders, xml parser, streams, etc, at the cost of making user code slightly more
* complicated. Therefore, this is a stopgap measure that WILL be removed at some point,
* once Objects are created.
*/
@typeof("resource")
public class CResource<T> extends Construct {
private static final AtomicLong resourcePool = new AtomicLong(0);
private final long id;
private final T resource;
private final ResourceToString toString;
/**
* Constructs a new CResource, given some underlying object.
* @param resource
* @param t
*/
public CResource(final T resource, Target t){
this(resource, new ResourceToString() {
@Override
public String getString(CResource id) {
// This is the original implementation of Object.toString()
String original = id.getResource().getClass().getName() + "@"
+ Integer.toHexString(id.getResource().hashCode());
String addendum = "";
if(!original.equals(id.getResource().toString())){
addendum = original + ":";
}
return "resource@" + id.getId() + ":"
+ addendum
+ id.getResource().toString();
}
}, t);
}
/**
* Constructs a new CResource, given some underlying object. The ResourceToString object allows you to override
* how this object is toString'd.
* @param resource
* @param toString
* @param t
*/
public CResource(T resource, ResourceToString toString, Target t){
super("", ConstructType.RESOURCE, t);
this.resource = resource;
if(toString == null){
throw new NullPointerException();
}
this.toString = toString;
id = resourcePool.incrementAndGet();
}
public long getId(){
return id;
}
public T getResource(){
return resource;
}
@Override
public String val() {
return toString.getString(this);
}
@Override
public String toString() {
return val();
}
@Override
public boolean isDynamic() {
return true;
}
@Override
public String docs() {
return "A resource is a value that represents an underlying native object. The object cannot be accessed directly.";
}
@Override
public Version since() {
return CHVersion.V3_3_1;
}
public static interface ResourceToString {
/**
* Returns a toString for the underlying object.
* @param self The actual resource being toString'd.
* @return
*/
String getString(CResource self);
}
}