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() )
|
||||
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;
|
||||
|
||||
@@ -298,8 +298,7 @@ public class LuaValue extends Varargs {
|
||||
|
||||
// lua number/string conversion
|
||||
public LuaString strvalue() { typerror("strValue"); return null; }
|
||||
public LuaValue strongvalue() { return this; }
|
||||
|
||||
public LuaValue strongvalue() { return this; }
|
||||
|
||||
// conversion from java values
|
||||
public static LuaBoolean valueOf(boolean b) { return b? LuaValue.TRUE: FALSE; };
|
||||
|
||||
@@ -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() {
|
||||
Object o = ref.get();
|
||||
if ( o == null ) {
|
||||
metatable = null;
|
||||
return NIL;
|
||||
if ( ref != null ) {
|
||||
Object o = ref.get();
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user