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