Let tables undergo mode changes.
This commit is contained in:
@@ -119,9 +119,34 @@ public class LuaTable extends LuaValue {
|
|||||||
if ( m_metatable!=null && !m_metatable.rawget(METATABLE).isnil() )
|
if ( m_metatable!=null && !m_metatable.rawget(METATABLE).isnil() )
|
||||||
error("cannot change a protected metatable");
|
error("cannot change a protected metatable");
|
||||||
m_metatable = metatable;
|
m_metatable = metatable;
|
||||||
|
LuaValue mode;
|
||||||
|
if ( m_metatable!=null && (mode=m_metatable.rawget(MODE)).isstring() ) {
|
||||||
|
String m = mode.toString();
|
||||||
|
return changemode(m.contains("k"),m.contains("v"));
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected LuaTable changemode(boolean weakkeys, boolean weakvalues) {
|
||||||
|
if ( weakkeys || weakvalues ) {
|
||||||
|
return recreateas(weakkeys, weakvalues);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected LuaTable recreateas(boolean weakkeys, boolean weakvalues) {
|
||||||
|
LuaTable t = weakkeys||weakvalues?
|
||||||
|
new WeakTable(weakkeys, weakvalues):
|
||||||
|
new LuaTable();
|
||||||
|
t.presize(array.length,hashKeys.length);
|
||||||
|
Varargs n;
|
||||||
|
LuaValue k = NIL;
|
||||||
|
while ( !(k = ((n = next(k)).arg1())).isnil() )
|
||||||
|
t.rawset(k, n.arg(2));
|
||||||
|
t.m_metatable = m_metatable;
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
public LuaValue get( int key ) {
|
public LuaValue get( int key ) {
|
||||||
LuaValue v = rawget(key);
|
LuaValue v = rawget(key);
|
||||||
return v.isnil() && m_metatable!=null? gettable(this,valueOf(key)): v;
|
return v.isnil() && m_metatable!=null? gettable(this,valueOf(key)): v;
|
||||||
|
|||||||
@@ -300,7 +300,6 @@ public class LuaValue extends Varargs {
|
|||||||
public LuaString strvalue() { typerror("strValue"); return null; }
|
public LuaString strvalue() { typerror("strValue"); return null; }
|
||||||
public LuaValue strongvalue() { return this; }
|
public LuaValue strongvalue() { return this; }
|
||||||
|
|
||||||
|
|
||||||
// conversion from java values
|
// conversion from java values
|
||||||
public static LuaBoolean valueOf(boolean b) { return b? LuaValue.TRUE: FALSE; };
|
public static LuaBoolean valueOf(boolean b) { return b? LuaValue.TRUE: FALSE; };
|
||||||
public static LuaInteger valueOf(int i) { return LuaInteger.valueOf(i); }
|
public static LuaInteger valueOf(int i) { return LuaInteger.valueOf(i); }
|
||||||
|
|||||||
@@ -38,36 +38,41 @@ public class WeakTable extends LuaTable {
|
|||||||
ref = new WeakReference(val);
|
ref = new WeakReference(val);
|
||||||
}
|
}
|
||||||
public int type() {
|
public int type() {
|
||||||
return LuaValue.TNIL;
|
return strongvalue().type();
|
||||||
}
|
}
|
||||||
public String typename() {
|
public String typename() {
|
||||||
return "value";
|
return "weakvalue";
|
||||||
}
|
}
|
||||||
public LuaValue strongvalue() {
|
public LuaValue strongvalue() {
|
||||||
Object o = ref.get();
|
Object o = ref.get();
|
||||||
return o!=null? (LuaValue)o: NIL;
|
return o!=null? (LuaValue)o: NIL;
|
||||||
}
|
}
|
||||||
|
public String toString() {
|
||||||
|
return strongvalue().toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class WeakUserdata extends LuaValue {
|
private static class WeakUserdata extends LuaValue {
|
||||||
private final WeakReference ref;
|
private WeakReference ref;
|
||||||
private LuaValue metatable;
|
private WeakReference mt;
|
||||||
public WeakUserdata(Object val, LuaValue metatable) {
|
public WeakUserdata(Object val, LuaValue metatable) {
|
||||||
ref = new WeakReference(val);
|
this.ref = new WeakReference(val);
|
||||||
|
this.mt = new WeakReference(metatable);
|
||||||
}
|
}
|
||||||
public int type() {
|
public int type() {
|
||||||
return LuaValue.TNIL;
|
return TVALUE;
|
||||||
}
|
}
|
||||||
public String typename() {
|
public String typename() {
|
||||||
return "value";
|
return "weakuserdata";
|
||||||
}
|
}
|
||||||
public LuaValue strongvalue() {
|
public LuaValue strongvalue() {
|
||||||
|
if ( ref != null ) {
|
||||||
Object o = ref.get();
|
Object o = ref.get();
|
||||||
if ( o == null ) {
|
if ( o != null )
|
||||||
metatable = null;
|
return userdataOf( o, (LuaValue) mt.get() );
|
||||||
return NIL;
|
|
||||||
}
|
}
|
||||||
return userdataOf( o, metatable );
|
ref = mt = null;
|
||||||
|
return NIL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,7 +140,7 @@ public class WeakTable extends LuaTable {
|
|||||||
v = v.strongvalue();
|
v = v.strongvalue();
|
||||||
if ( v.isnil() ) {
|
if ( v.isnil() ) {
|
||||||
// TODO: mark table for culling?
|
// TODO: mark table for culling?
|
||||||
rawset(key, NIL);
|
super.rawset(key, NIL);
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
@@ -147,7 +152,7 @@ public class WeakTable extends LuaTable {
|
|||||||
v = v.strongvalue();
|
v = v.strongvalue();
|
||||||
if ( v.isnil() ) {
|
if ( v.isnil() ) {
|
||||||
// TODO: mark table for culling?
|
// TODO: mark table for culling?
|
||||||
rawset(key, NIL);
|
super.rawset(key, NIL);
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
@@ -176,4 +181,12 @@ public class WeakTable extends LuaTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected LuaTable changemode(boolean k, boolean v) {
|
||||||
|
if ( k!=this.weakKeys || v!=weakValues )
|
||||||
|
return recreateas(k,v);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -317,8 +317,7 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
|||||||
case 13: { // "setmetatable", // (table, metatable) -> table
|
case 13: { // "setmetatable", // (table, metatable) -> table
|
||||||
final LuaValue t = args.arg1();
|
final LuaValue t = args.arg1();
|
||||||
final LuaValue mt = args.checkvalue(2);
|
final LuaValue mt = args.checkvalue(2);
|
||||||
t.setmetatable(mt.isnil()? null: mt.checktable());
|
return t.setmetatable(mt.isnil()? null: mt.checktable());
|
||||||
return t;
|
|
||||||
}
|
}
|
||||||
case 14: { // "tostring", // (e) -> value
|
case 14: { // "tostring", // (e) -> value
|
||||||
LuaValue arg = args.checkvalue(1);
|
LuaValue arg = args.checkvalue(1);
|
||||||
|
|||||||
Reference in New Issue
Block a user