Exemplo n.º 1
0
        internal object ToObject(int index, LuaType?typeHint = null, IntPtr?stateOverride = null)
        {
            var state = stateOverride ?? MainState;

            Debug.Assert(LuaApi.GetMainState(state) == MainState, "State override did not match main state.");
            var type = typeHint ?? LuaApi.Type(state, index);

            Debug.Assert(type == LuaApi.Type(state, index), "Type hint did not match type.");

            switch (type)
            {
            case LuaType.None:
            case LuaType.Nil:
                return(null);

            case LuaType.Boolean:
                return(LuaApi.ToBoolean(state, index));

            case LuaType.Number:
                var isInteger = LuaApi.IsInteger(state, index);
                return(isInteger ? LuaApi.ToInteger(state, index) : (object)LuaApi.ToNumber(state, index));

            case LuaType.String:
                return(LuaApi.ToString(state, index));

            case LuaType.Userdata:
                var handle = LuaApi.ToHandle(state, index);
                return(handle.Target);
            }

            LuaReference luaReference = null;
            var          pointer      = LuaApi.ToPointer(state, index);

            if (_cachedLuaReferences.TryGetValue(pointer, out var weakReference))
            {
                luaReference = (LuaReference)weakReference.Target;
                if (luaReference != null)
                {
                    return(luaReference);
                }
            }

            LuaApi.PushValue(state, index);
            var referenceId = LuaApi.Ref(state, LuaApi.RegistryIndex);

            switch (type)
            {
            case LuaType.Table:
                luaReference = new LuaTable(this, referenceId);
                break;

            case LuaType.Function:
                luaReference = new LuaFunction(this, referenceId);
                break;

            case LuaType.Thread:
                luaReference = new LuaThread(this, referenceId, pointer);
                break;
            }

            if (weakReference != null)
            {
                weakReference.Target = luaReference;
            }
            else
            {
                _cachedLuaReferences[pointer] = new WeakReference(luaReference);
            }
            _pointerToReferenceId[pointer] = referenceId;
            return(luaReference);
        }