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() )
error("cannot change a protected 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;
}
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 ) {
LuaValue v = rawget(key);
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 LuaValue strongvalue() { return this; }
// conversion from java values
public static LuaBoolean valueOf(boolean b) { return b? LuaValue.TRUE: FALSE; };
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);
}
public int type() {
return LuaValue.TNIL;
return strongvalue().type();
}
public String typename() {
return "value";
return "weakvalue";
}
public LuaValue strongvalue() {
Object o = ref.get();
return o!=null? (LuaValue)o: NIL;
}
public String toString() {
return strongvalue().toString();
}
}
private static class WeakUserdata extends LuaValue {
private final WeakReference ref;
private LuaValue metatable;
private WeakReference ref;
private WeakReference mt;
public WeakUserdata(Object val, LuaValue metatable) {
ref = new WeakReference(val);
this.ref = new WeakReference(val);
this.mt = new WeakReference(metatable);
}
public int type() {
return LuaValue.TNIL;
return TVALUE;
}
public String typename() {
return "value";
return "weakuserdata";
}
public LuaValue strongvalue() {
if ( ref != null ) {
Object o = ref.get();
if ( o == null ) {
metatable = null;
return NIL;
if ( o != null )
return userdataOf( o, (LuaValue) mt.get() );
}
return userdataOf( o, metatable );
ref = mt = null;
return NIL;
}
}
@@ -135,7 +140,7 @@ public class WeakTable extends LuaTable {
v = v.strongvalue();
if ( v.isnil() ) {
// TODO: mark table for culling?
rawset(key, NIL);
super.rawset(key, NIL);
}
return v;
}
@@ -147,7 +152,7 @@ public class WeakTable extends LuaTable {
v = v.strongvalue();
if ( v.isnil() ) {
// TODO: mark table for culling?
rawset(key, NIL);
super.rawset(key, NIL);
}
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
final LuaValue t = args.arg1();
final LuaValue mt = args.checkvalue(2);
t.setmetatable(mt.isnil()? null: mt.checktable());
return t;
return t.setmetatable(mt.isnil()? null: mt.checktable());
}
case 14: { // "tostring", // (e) -> value
LuaValue arg = args.checkvalue(1);