diff --git a/luprex/lua/control.lst b/luprex/lua/control.lst index 0425faf0..a92c13fb 100644 --- a/luprex/lua/control.lst +++ b/luprex/lua/control.lst @@ -5,4 +5,5 @@ ut-table.lua ut-tablecmp.lua +hotkeys.lua login.lua diff --git a/luprex/lua/hotkeys.lua b/luprex/lua/hotkeys.lua new file mode 100644 index 00000000..7f90196d --- /dev/null +++ b/luprex/lua/hotkeys.lua @@ -0,0 +1,82 @@ +---------------------------------------------------------------- +-- +-- To add hotkeys to an object (such as a Brick Oven), you will +-- be adding a function 'lookhotkeys' to the appropriate class, +-- like this: +-- +-- function brickoven.lookhotkeys(keys) +-- keys:add("X", "Light Oven", function () ... end) +-- keys:add("A", "Add Fuel", function () ... end) +-- end +-- +-- This function will get called twice: once in a 'probe' when +-- Unreal wants to know what hotkeys exist, and a second time in +-- an 'invoke' to find the right closure. +-- +-- When the probe happens, we construct a "hotkeylist" to hold +-- the complete list of hotkeys. We populate this hotkeylist as +-- follows: +-- +-- local keys = hotkeylist.create() +-- brickoven.lookhotkeys(keys) +-- +-- At this point, if you were to pprint(keys), the output would +-- look like this: +-- +-- { "hotkeys", "X", "Light Oven", "A", "Add Fuel" } +-- +-- The first array element is always the word "hotkeys". Notice +-- also that a hotkeylist doesn't store the closures, they are +-- silently ignored. The resulting array is in a format that can +-- be returned directly to Unreal. +-- +-- Later, when the user presses a key, such as the "Light Oven" key, +-- we will construct a "hotkeypress" object whose job is to record +-- the name of the hotkey that was pressed, and the closure that +-- goes with it. We populate this object as follows: +-- +-- local keys = hotkeypress.create("Light Oven") +-- brickoven.lookhotkeys(keys) +-- +-- So as you can see, we're using the same 'brickoven.lookhotkeys' +-- function, but this time, we've passed in a parameter of class +-- hotkeypress instead of a parameter of class hotkeylist. This +-- changes the behavior of the 'add' method: the add function of +-- a hotkeylist stores all the hotkeys into the list. But the 'add' +-- function of a hotkeypress only stores the one closure that +-- we are interested in. If you were to pprint(keys), the result +-- would look like this: +-- +-- { pressed="Light Oven", closure= } +-- +-- So the only data stored by a 'hotkeypress' object is the name +-- of the pressed hotkey, and the closure that goes with it. +-- +---------------------------------------------------------------- + +makeclass("hotkeylist") +makeclass("hotkeypress") + +function hotkeylist.create() + local result = { "hotkeys" } + setmetatable(result, hotkeylist) + return result +end + +function hotkeylist.add(self, key, action, closure) + table.insert(self, key) + table.insert(self, action) +end + +function hotkeypress.create(key) + local result = { pressed=key } + setmetatable(result, hotkeypress) + return result +end + +function hotkeypress.add(self, key, action, closure) + if action == self.pressed then + self.closure = closure + end +end + diff --git a/luprex/lua/login.lua b/luprex/lua/login.lua index d706fd19..3ebe8ff8 100644 --- a/luprex/lua/login.lua +++ b/luprex/lua/login.lua @@ -18,22 +18,34 @@ function engio.move(action, xyz, facing) tangible.animate(actor, nil, {action=action, xyz=xyz, facing=facing}) end -function cube.getlookat() - return { "Hotkeys", "X", "I Am a Cube" } +function cube.lookhotkeys(keys) + keys:add("X", "Cube Hi", function () dprint("Cube Hi") end) + keys:add("A", "Cube Bye", function () dprint("Cube Bye") end) end -function sphere.getlookat() - return { "Hotkeys", "X", "I Am a Sphere" } +function sphere.lookhotkeys(keys) + keys:add("X", "Sphere Hi", function () dprint("Sphere Hi") end) + keys:add("A", "Sphere Bye", function () dprint("Sphere Bye") end) end + function engio.getlookat() local class = tangible.getclass(tangible.place()) - if class ~= nil then - local getlookat = class.getlookat - if getlookat ~= nil then - return getlookat() - end + if class == nil then return end + + -- if the class has a function 'lookhotkeys', then the correct + -- look-at widget is 'hotkeys'. We're going to automatically + -- generate the correct response. + if class.lookhotkeys ~= nil then + local keys = hotkeylist.create() + class.lookhotkeys(keys) + setmetatable(keys, nil) + return keys + end + + -- otherwise, if the class has a function 'getlookat', use that. + if class.getlookat ~= nil then + return class.getlookat() end - return "" end