CraftTweaker / ZenScript

MIT License
77 stars 22 forks source link

Using custom ZS class as instance variable fails #12

Closed codetaylor closed 6 years ago

codetaylor commented 6 years ago

ZenScript:

zenClass ClassA {
  var value as int;
  zenConstructor(value as int) {
    this.value = value;
  }
}

zenClass ClassB {
  var value as ClassA;
  zenConstructor(value as ClassA) {
    this.value = value;
  }
}

var cA = ClassA(42);
var cB = ClassB(cA);

Compiled ClassA:

public class ZenClass0 {
  public int value;

  public ZenClass0(int var1) {
    this.value = var1;
  }
}

Compiled ClassB:

import stanhebben.zenscript.value.IAny;

public class ZenClass1 {
  public IAny value;

  public ZenClass1(IAny var1) {
    this.value = var1;
  }
}

Compiled script:

public class Test implements Runnable {
  public static void __script__() {
    new ZenClass0(42);
    Object var3 = null;
  }
}

Log:

[SERVER_STARTED][SERVER][INFO] Loading scripts
[SERVER_STARTED][SERVER][INFO] Debug Preprocessor found in {[100:crafttweaker]: test.zs}, enabling debugmode
[SERVER_STARTED][SERVER][INFO] [crafttweaker | SIDE_CLIENT]: Loading Script: {[100:crafttweaker]: test.zs}
[SERVER_STARTED][SERVER][ERROR] Could not find constructor for ClassBwith 1 arguments.
[SERVER_STARTED][SERVER][INFO] Completed script loading in: 6ms
codetaylor commented 6 years ago

Casting seemed to fix the error:

...
var cA as ClassA = ClassA(42);
var cB as ClassB = ClassB(cA);

Compiled:

public class Test implements Runnable {
  public static void __script__() {
    ZenClass0 var1 = new ZenClass0(42);
    new ZenClass1(var1);
  }
}

The instance variable in ClassB is still declared as IAny though.

codetaylor commented 6 years ago

Then trying to access the value gives an error:

print("Value: " ~ cB.value);
print("Value: " ~ cB.value.value);

Log:

[SERVER_STARTED][SERVER][INFO] Loading scripts
[SERVER_STARTED][SERVER][INFO] Debug Preprocessor found in {[100:crafttweaker]: test.zs}, enabling debugmode
[SERVER_STARTED][SERVER][INFO] [crafttweaker | SIDE_CLIENT]: Loading Script: {[100:crafttweaker]: test.zs}
[SERVER_STARTED][SERVER][ERROR] test.zs:21 > any values not yet supported
[SERVER_STARTED][SERVER][INFO] Completed script loading in: 8ms
kindlich commented 6 years ago

Can you try using a second script file (which should obviously be loaded after the current one) in which you declare ClassB? You may be able to use scripts.scriptName.ClassA as type.

I didn't expect people to use instance variables of other classes so I didn't expose them to the type registry at that time, hence an unknown type hence IAny.

codetaylor commented 6 years ago

Ok, I was able to play with it some more and split ClassA into a separate file per your suggestion.

The following code works and allows classes as instance variables with the caveat that variables can't be typecast as a class if the class is declared in the same file.

TestA.zs:

#priority 100
#debug

zenClass ClassA {
  var value as int;
  zenConstructor(value as int) {
    this.value = value;
  }
}

ClassA compiled:

public class ZenClass0 {
  public int value;

  public ZenClass0(int var1) {
    this.value = var1;
  }
}

TestB.zs:

#priority 10
#debug

zenClass ClassB {
  var value as scripts.testA.ClassA;
  zenConstructor(value as scripts.testA.ClassA) {
    this.value = value;
  }
}

var cB = ClassB(scripts.testA.ClassA(42));

print("Value: " ~ cB.value.value);

ClassB compiled:

public class ZenClass1 {
  public ZenClass0 value;

  public ZenClass1(ZenClass0 var1) {
    this.value = var1;
  }
}

TestB.zs compiled:

import crafttweaker.runtime.GlobalFunctions;

public class TestB implements Runnable {
  public static void __script__() {
    ZenClass1 var1 = new ZenClass1(new ZenClass0(42));
    GlobalFunctions.print("Value: " + Integer.toString(var1.value.value));
  }
}

Log:

[INITIALIZATION][CLIENT][INFO] CraftTweaker: Building registry
[INITIALIZATION][CLIENT][INFO] CraftTweaker: Successfully built item registry
[INITIALIZATION][CLIENT][INFO] Loading scripts
[INITIALIZATION][CLIENT][INFO] Debug Preprocessor found in {[100:crafttweaker]: testA.zs}, enabling debugmode
[INITIALIZATION][CLIENT][INFO] Debug Preprocessor found in {[10:crafttweaker]: testB.zs}, enabling debugmode
[INITIALIZATION][CLIENT][INFO] [crafttweaker | SIDE_CLIENT]: Loading Script: {[100:crafttweaker]: testA.zs}
[INITIALIZATION][CLIENT][INFO] [crafttweaker | SIDE_CLIENT]: Loading Script: {[10:crafttweaker]: testB.zs}
[INITIALIZATION][CLIENT][INFO] Value: 42
[INITIALIZATION][CLIENT][INFO] Completed script loading in: 460ms
kindlich commented 6 years ago

Err.. remind me, did I fix this? The example in the first message seemed to work for me, can you confirm?

codetaylor commented 6 years ago

@kindlich I checked the first example an it worked for me. So, yeah, I think that this has been taken care of. Thanks!