I've been sitting on this for quite a while, and finally decided to post it here one bored evening.
This is a Queue Manager, for handling multiple actions you might like to take in sequence. It was designed with a balance-based MuD in mind (the IRE MuDs, specifically), but it's generic enough to work with any MuD; it can be used with or without a flag-variable of some sort. There is no fancy logic in here; it's a fairly straightforward FIFO list, save that it will distinguish between actions that require balance and those that consume balance, and execute all actions that only require balance first.
Below is the guide, as found in the package itself:
---- QeMistry Queue Manager
--- Written by Oneymus, http://forums.mudlet.org/
--[[
May 2010
Updated April 2011
Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
--]]
---- Usage Guide
--- <queue> = QeM.Queue:new( <balance as a string, table of strings, a function, a table of functions, or boolean value>, [<option as a single string, or a table of options>] )
--[[
This will instantiate a new Queue.
If passed a string value, that string must point to a boolean variable acting as "balance."
Example: = QeM.Queue:new( "my_system.balance_variables.balance" ) or
= QeM.Queue:new( "balance_variable" )
If passed a table value, that table must contain a list of strings, functions, or some combination thereof.
In Lua, any value that is not false or nil will evaluate to true. Keep this in mind when passing a
function; also, that function must return a value.
Example: = QeM.Queue:new( {"balance", "equilibrium"} ) or
= QeM.Queue:new( {"my_system.balance", "my_system.equilibrium"} )
= QeM.Queue:new( function () return my_system.balance end )
= QeM.Queue:new( {"my_system.balance", function () return my_system.equilibrium end} )
= QeM.Queue:new( somePredefinedFunction() )
If passed a boolean, it must be true, or the Queue won't work.
Example: = QeM.Queue:new( true )
Options are passed the following ways, and are optional:
Example: = QeM.Queue:new( "balance", "strict_order" )
= QeM.Queue:new( "balance", {"strict_order", "single_step"} )
Currently supported options are:
strict_order: Maintains the order of actions in the Queue, regardless of consumed or required
balance. When executing actions that consume balance, the Queue will need to be manually
re-executed (or the act() call included in the code of the consumed action itself).
single_step: The Queue does not re-execute itself, except in the case of a consumed balance going
unconsumed.
--]]
--- <queue>:add( <action as a table containing a code field, and a required and/or consumed field> )
--- <queue>:add( <action as a string or function> )
--[[
If passed a string or function, then QeMistry assumes the action requires, but does not consume
the same balance as the Queue itself. This string or function must contain the action to be taken.
If the value is a string, that value will be sent to the MuD as a command using the Mudlet function
send(). If the value is a function, it will be executed when the Queue calls for it.
Example: add( function () echo( "Do stuff!" ) end ) or
add( "Do stuff!" )
If passed a table, then the table may contain a code field. This code field, or the table itself, must
contain a list of strings or functions to be executed.
Example: add( {code = {"Do stuff!", "Do more stuff!"}} ) or
add( {function () echo( "Do stuff!" ) end, function () echo( "Do more stuff!" ) end} ) or
add( {"Do stuff!", function () echo( "Do more stuff!") end} )
Optionally, the table can contain either/both a required field and/or a consumed field. If the table
contains a required or consumed field, the code must be enclosed in a code field. These fields must be a
string pointing to a boolean variable acting as "balance," or a function that will return a boolean value.
In the case of the required field, this can be a boolean value itself. If these fields are omitted,
then it is assumed this action requires the same balance as the Queue itself.
Example: add( {code = "code", required = "my_system.balance"} ) or
add( {code = "code", consumed = "my_system.balance"} ) or
add( {code = "code", required = "my_system.balance", consumed = "my_system.equilibrium"} )
add( {code = "code", required = "my_system.balance", consumed = function () return my_system.equilibrium end} )
You can pass both the consumed and required fiels as tables for multiple balances.
Example: add( {code = "code", required = {"my_system.balance", "my_system.equilibrium"} )
add( {code = "code", required = {function () return my_system.balance end, somePredefinedFunction()}} )
--]]
--- <queue>:reset()
--[[
This will empty the action list for the Queue.
--]]
--- <queue>:act()
--[[
This is to be called whenever the Queue should process the next action in its list.
The Queue will first check to see if the balance variable it points to contains true.
If so, then it will make sure there are actions in its action list.
Next, the Queue will run through all actions in its action list that contain a required field,
but not a consumed field, and execute them.
Finally, it will execute the first action in its list that contains a consumed field.
The Queue itself does not change the balance variable pointed to by the consumed field; instead,
it uses a 0.5 second tempTimer to check that balance variable to make sure it has been set to false.
If that variable is not false, it reinserts the attempted action at the beginning of the Queue's
action list.
--]]
As always, post here if you have questions, find bugs, or require some feature (I have in mind automatic actions that execute between other actions, for example). I will respond to inquires and concerns, and I may be motivated to add features based on interest.
Alternatively, you can send me a PM, but if it's a question you think might be of benefit to all involved, it'd be better to leave it here.
And, who knows, if this proves popular I might be motivated enough to finally finish my GUI framework I've been sitting on for a long, long time.
Updated April 2011:
- Added support for options:
- strict_order: Will preserve the order of actions in the queue, regardless of balance consumption.
- single_step: Will only execute a single action at a time.
- Added support for functions in balance fields.
- Fixed a bug in getField(); was trying to pass a table to gfind, which it did not appreciate.
- Removed some leftover debug messages, which were probably annoying. Hopefully, I didn't repeat that mistake.
- Fixed a bug in the tempTimer generated by consumed actions. Specifically, the table version was incorrectly judging whether or not the action needed to be re-executed if it used multiple balances.