-
-
Save datatypevoid/744bb541cdc70ec9b9d07aaa24f9ed3d to your computer and use it in GitHub Desktop.
Safe reference implementation. Lua part. See https://eliasdaler.github.io/game-object-references for details
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Handles = {} | |
| local memoizedFuncs = {} | |
| -- metatable which does magic | |
| local mt = {} | |
| mt.__index = function(handle, key) | |
| if not handle.isValid then | |
| print(debug.traceback()) | |
| error("Error: handle is not valid!", 2) | |
| end | |
| local f = memoizedFuncs[key] | |
| if not f then | |
| f = function(handle, ...) return Entity[key](handle.cppRef, ...) end | |
| memoizedFuncs[key] = f | |
| end | |
| return f | |
| end | |
| function getWrappedSafeFunction(f) | |
| return function(handle, ...) | |
| if not handle.isValid then | |
| print(debug.traceback()) | |
| error("Error: handle is not valid!", 2) | |
| end | |
| return f(handle.cppRef, ...) | |
| end | |
| end | |
| function createHandle(cppRef) | |
| local handle = { | |
| cppRef = cppRef, | |
| isValid = true | |
| } | |
| -- speedy access without __index call | |
| handle.getName = getWrappedSafeFunction(Entity.getName) | |
| setmetatable(handle, mt) | |
| Handles[cppRef:getId()] = handle | |
| return handle | |
| end | |
| function onEntityRemoved(cppRef) | |
| local handle = Handles[cppRef:getId()]; | |
| handle.cppRef = nil | |
| handle.isValid = false | |
| Handles[cppRef:getId()] = nil | |
| end | |
| function test(cppRef) | |
| local handle = createHandle(cppRef) | |
| testHandle(handle) | |
| end | |
| function testHandle(handle) | |
| print("Hello, my name is " .. handle:getName()) | |
| handle:setName("Mark") | |
| print("My name is " .. handle:getName() .. " now!") | |
| end | |
| function testBadReference() | |
| local handle = Handles[0] -- this handle exists and is okay | |
| handle.isValid = false -- but suppose that entity was removed! | |
| local _, err = pcall(testHandle, handle) | |
| if err then | |
| print(err) | |
| end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment