package php.runtime.ext.core.classes;
import php.runtime.Memory;
import php.runtime.common.HintType;
import php.runtime.env.Environment;
import php.runtime.invoke.Invoker;
import php.runtime.lang.BaseObject;
import php.runtime.lang.support.IComparableObject;
import php.runtime.memory.ArrayMemory;
import php.runtime.memory.LongMemory;
import php.runtime.memory.ObjectMemory;
import php.runtime.memory.StringMemory;
import php.runtime.reflection.ClassEntity;
import static php.runtime.annotation.Reflection.*;
@Name("php\\lang\\Thread")
public class WrapThread extends BaseObject implements IComparableObject<WrapThread> {
public static final int MAX_PRIORITY = Thread.MAX_PRIORITY;
public static final int MIN_PRIORITY = Thread.MIN_PRIORITY;
public static final int NORM_PRIORITY = Thread.NORM_PRIORITY;
protected Environment customEnv;
protected Thread thread;
protected Invoker invoker;
public WrapThread(Environment env) {
super(env);
}
public WrapThread(Environment env, Thread thread) {
super(env);
setThread(thread, env);
}
public WrapThread(Environment env, ClassEntity clazz) {
super(env, clazz);
}
public Environment getCustomEnv() {
return customEnv;
}
public void setCustomEnv(Environment customEnv) {
this.customEnv = customEnv;
}
public Thread getThread() {
return thread;
}
public void setThread(Thread thread, Environment env) {
this.thread = thread;
if (thread != null) {
Environment.addThreadSupport(thread, env);
}
}
@Signature({
@Arg(value = "runnable", type = HintType.CALLABLE),
@Arg(value = "env", typeClass = "php\\lang\\Environment", optional = @Optional("NULL")),
@Arg(value = "group", typeClass = "php\\lang\\ThreadGroup", optional = @Optional("NULL"))
})
public Memory __construct(Environment env, Memory... args) {
if (!args[1].isNull())
setCustomEnv(args[1].toObject(WrapEnvironment.class).getWrapEnvironment());
else
setCustomEnv(env);
final Invoker invoker = Invoker.valueOf(getCustomEnv(), null, args[0]);
ThreadGroup group = null;
if (!args[2].isNull()) {
group = args[2].toObject(WrapThreadGroup.class).getGroup();
}
this.invoker = invoker;
if (args[2].isNull()) {
setThread(new Thread(group, new Runnable() {
@Override
public void run() {
invoker.callNoThrow();
}
}), env);
} else {
setThread(new Thread(group, new Runnable() {
@Override
public void run() {
invoker.callNoThrow();
}
}, args[2].toString()), env);
}
return Memory.NULL;
}
@Signature
public Memory __debugInfo(Environment env, Memory... args) {
ArrayMemory r = new ArrayMemory();
r.refOfIndex("*id").assign(thread.getId());
r.refOfIndex("*name").assign(thread.getName());
if (thread.getThreadGroup() != null)
r.refOfIndex("*group").assign(thread.getThreadGroup().getName());
else
r.refOfIndex("*group");
r.refOfIndex("*priority").assign(thread.getPriority());
return r.toConstant();
}
@Signature
public Memory getId(Environment env, Memory... args) {
return LongMemory.valueOf(thread.getId());
}
@Signature
public Memory getName(Environment env, Memory... args){
return new StringMemory(thread.getName());
}
@Signature
public Memory getPriority(Environment env, Memory... args){
return LongMemory.valueOf(thread.getPriority());
}
@Signature(@Arg("value"))
public Memory setPriority(Environment env, Memory... args){
thread.setPriority(args[0].toInteger());
return Memory.NULL;
}
@Signature
public Memory getState(Environment env, Memory... args){
return new StringMemory(thread.getState().name());
}
@Signature
public Memory setDaemon(Environment env, Memory... args){
thread.setDaemon(args[0].toBoolean());
return Memory.NULL;
}
@Signature
public Memory isDaemon(Environment env, Memory... args){
return thread.isDaemon() ? Memory.TRUE : Memory.FALSE;
}
@Signature
public Memory isAlive(Environment env, Memory... args){
return thread.isAlive() ? Memory.TRUE : Memory.FALSE;
}
@Signature
public Memory isInterrupted(Environment env, Memory... args){
return thread.isInterrupted() ? Memory.TRUE : Memory.FALSE;
}
@Signature(@Arg("name"))
public Memory setName(Environment env, Memory... args){
thread.setName(args[0].toString());
return Memory.NULL;
}
@Signature
public Memory interrupt(Environment env, Memory... args){
thread.interrupt();
return Memory.NULL;
}
@Signature
public Memory start(Environment env, Memory... args){
invoker.setTrace(env.trace());
thread.start();
return Memory.NULL;
}
@Signature
public Memory run(Environment env, Memory... args){
invoker.setTrace(env.trace());
thread.run();
return Memory.NULL;
}
@Signature
public Memory getGroup(Environment env, Memory... args){
if (thread.getThreadGroup() == null)
return Memory.NULL;
return new ObjectMemory(new WrapThreadGroup(env, thread.getThreadGroup()));
}
@Signature({
@Arg(value = "millis", optional = @Optional(value = "0", type = HintType.INT)),
@Arg(value = "nanos", optional = @Optional(value = "0", type = HintType.INT))
})
public Memory join(Environment env, Memory... args) throws InterruptedException {
thread.join(args[0].toLong(), args[1].toInteger());
return Memory.NULL;
}
@Signature
public static Memory doYield(Environment env, Memory... args){
Thread.yield();
return Memory.NULL;
}
@Signature
public static Memory getActiveCount(Environment env, Memory... args){
return LongMemory.valueOf(Thread.activeCount());
}
@Signature
public static Memory current(Environment env, Memory... args){
return new ObjectMemory(new WrapThread(env, Thread.currentThread()));
}
@Signature({@Arg("millis"), @Arg(value = "nanos", optional = @Optional(value = "0", type = HintType.INT))})
public static Memory sleep(Environment env, Memory... args) throws InterruptedException {
Thread.sleep(args[0].toLong(), args[1].toInteger());
return Memory.NULL;
}
@Override
public boolean __equal(WrapThread iObject) {
return thread == iObject.thread;
}
@Override
public boolean __identical(WrapThread iObject) {
return thread == iObject.thread;
}
@Override
public boolean __greater(WrapThread iObject) {
return false;
}
@Override
public boolean __greaterEq(WrapThread iObject) {
return false;
}
@Override
public boolean __smaller(WrapThread iObject) {
return false;
}
@Override
public boolean __smallerEq(WrapThread iObject) {
return false;
}
}