예제 #1
0
        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);
        }
예제 #2
0
        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.
            }
        }
예제 #3
0
        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);
        }
예제 #4
0
            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);
            }