public void Add(LuaValue key, LuaValue value) { CheckDisposed(); if (key.IsNil()) { throw new ArgumentNullException("key"); } Runtime.Push(this); Runtime.Push(key); LuaApi.lua_gettable(Runtime.LuaState, -2); if (LuaApi.lua_type(Runtime.LuaState, -1) != LuaApi.LuaType.Nil) { // Slot is occupied. LuaApi.lua_pop(Runtime.LuaState, 2); throw new ArgumentException("Table already contains given key.", "key"); } // Slot is unoccupied. Leave the nil there for now, we'll pop ALL the things at the end. Runtime.Push(key); Runtime.Push(value); LuaApi.lua_settable(Runtime.LuaState, -4); // Pop table and nil value. LuaApi.lua_pop(Runtime.LuaState, 2); }
public void Clear() { CheckDisposed(); Runtime.Push(this); // Go over each key and remove it until the table is empty. for (;;) { LuaApi.lua_pushnil(Runtime.LuaState); if (LuaApi.lua_next(Runtime.LuaState, -2) == 0) { // Table is empty. LuaApi.lua_pop(Runtime.LuaState, 1); break; } // Replace the value with nil and set the key. LuaApi.lua_pop(Runtime.LuaState, 1); LuaApi.lua_pushnil(Runtime.LuaState); LuaApi.lua_settable(Runtime.LuaState, -3); // Next iteration will start from the next key by using a nil key again. } }
protected override LuaValue CopyReferenceImpl() { CheckDisposed(); // We need to take a new reference, so we will let Runtime.Wrap() build the copy. Runtime.Push(this); var copy = Runtime.Wrap(-1); LuaApi.lua_pop(Runtime.LuaState, 1); return(copy); }
public LuaValue this[LuaValue key] { get { CheckDisposed(); var top = LuaApi.lua_gettop(Runtime.LuaState); Runtime.Push(this); Runtime.Push(key); LuaApi.lua_gettable(Runtime.LuaState, -2); LuaValue val; try { val = Runtime.Wrap(-1); } finally { LuaApi.lua_settop(Runtime.LuaState, top); } return(val); } set { CheckDisposed(); // Lua allows one to query the nil index (always returning nil) but never to set it. if (key.IsNil()) { throw new ArgumentNullException("key"); } var top = LuaApi.lua_gettop(Runtime.LuaState); Runtime.Push(this); Runtime.Push(key); Runtime.Push(value); LuaApi.lua_settable(Runtime.LuaState, -3); LuaApi.lua_settop(Runtime.LuaState, top); } }
public bool MoveNext() { CheckDisposed(); // Fast-fail if we reached the end previously. if (atEnd) { return(false); } var runtime = table.Runtime; runtime.Push(table); // Will push nil on first iteration, which is exactly what lua_next() expects. runtime.Push(currentKey); if (LuaApi.lua_next(runtime.LuaState, -2) == 0) { // At the end, so only the table is on the stack now. atEnd = true; LuaApi.lua_pop(runtime.LuaState, 1); return(false); } var newValue = runtime.Wrap(-1); var newKey = runtime.Wrap(-2); current = new KeyValuePair <LuaValue, LuaValue>(newKey, newValue); if (currentKey != null) { currentKey.Dispose(); } currentKey = current.Key.CopyReference(); LuaApi.lua_pop(runtime.LuaState, 3); return(true); }
internal override void Push(LuaRuntime runtime) { LuaApi.lua_pushnumber(runtime.LuaState, Value); }
internal override void Push(LuaRuntime runtime) { LuaApi.lua_pushvalue(runtime.LuaState, LuaApi.LUA_GLOBALSINDEX); }
internal override void Push(LuaRuntime runtime) { LuaApi.lua_pushnil(runtime.LuaState); }
internal override void Push(LuaRuntime runtime) { LuaApi.lua_pushlstring(runtime.LuaState, Value, new UIntPtr((ulong)Value.Length)); }
internal override void Push(LuaRuntime runtime) { LuaApi.lua_pushboolean(runtime.LuaState, Value ? 1 : 0); }