Let tables undergo mode changes.

This commit is contained in:
James Roseborough
2010-04-19 03:33:48 +00:00
parent 494e4206c4
commit fdea0828fc
4 changed files with 54 additions and 18 deletions

View File

@@ -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;

View File

@@ -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); }

View File

@@ -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;
}
} }

View File

@@ -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);