QeMistry Queue Manager

Share your scripts and packages with other Mudlet users.
User avatar
Oneymus
Posts: 321
Joined: Thu Sep 17, 2009 5:24 am

QeMistry Queue Manager

Post by Oneymus »

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:
Code: [show] | [select all] lua
---- 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.
2011 04 20 QeMistry.xml
QeMistry Queue Manager
(17.31 KiB) Downloaded 636 times
Last edited by Oneymus on Wed Apr 20, 2011 10:47 am, edited 4 times in total.

User avatar
keneanung
Site Admin
Posts: 94
Joined: Mon Mar 21, 2011 9:36 am
Discord: keneanung#2803

Re: QeMistry Queue Manager

Post by keneanung »

I've been looking at your queing system, which looks pretty usable. But there's something I'd like to have added.

In Achaea, most things you do require you to have both balance and equilibrum. I personally would like to track both independent from each other, but compose them for those things. I can think of two options;
1. give a function to the Queue in the required field
2. give a numeric table of needed balances to the queue in the requred field

I don't know which one may be easier to implement or more usefull, but maybe the function offers more options than just tracking multiple balances. So it might be able to track even multiple other conditions that may prevent certain things.

User avatar
Oneymus
Posts: 321
Joined: Thu Sep 17, 2009 5:24 am

Re: QeMistry Queue Manager

Post by Oneymus »

Actions can have balance requirements independent of the Queue's balance; this was done with IRE abilities in mind.

So, you can have a Balance Queue, with Actions that consume Balance -and- require Equilibrium. Or you can have a Queue itself that consumes Balance and requires Equilibrium. It's fairly flexible in that regard. You can supply tables for both Consumed and Required fields, and have both fields.

dlz
Posts: 4
Joined: Sun Apr 03, 2011 10:03 am

Re: QeMistry Queue Manager

Post by dlz »

Can you post a more comprehensive example of the syntax for this script? I must be doing something wrong because it's kicking back an error that I'm trying to index local v, a nil value. I have a table (named "actions") of strings I want to execute, they all require both balance and equilibrium but only consume equilibrium.

User avatar
Oneymus
Posts: 321
Joined: Thu Sep 17, 2009 5:24 am

Re: QeMistry Queue Manager

Post by Oneymus »

The variable v is used exclusively in QeM.Utility.getField. This suggests to me that it's not finding the variable you supplied for either balance or equilibrium. That being said, I will try and provide more concrete examples.

First, let's set up our "system".
Code: [show] | [select all] lua
-- Holds all system variables. For this example, just has our two balances.
my_system = my_system or {
  balances = my_system.balances or {
    equilibrium = false,
    balance = false,
    }
}
Next, we need to make our Queue.
Code: [show] | [select all] lua
-- We'll make it for balance.
balQueue = QeM.Queue:new( "my_system.balances.balance" )
So, we have our Queue, and it won't act (and accidentally burn our actions) unless my_system.balances.balance == true. Let's add some actions.
Code: [show] | [select all] lua
-- Since we don't specify required or consumed, it assumes that this only requires balance to be true.
balQueue:add( "diagnose" )

-- Same here, but this is a function, so it doesn't automatically send it as a MuD command.
balQueue:add( function () echo( "This is a test echo from balQueue.\n" ) end )

-- This action requires balance to be true, but it consumes equilibrium (also requiring it to be true).
balQueue:add( {code = "cast waterwalk", required = "my_system.balances.balance", consumed = "my_system.balances.equilibrium"} )

-- This executes these two actions (the MuD look command and the Mudlet function) one right after the other.
-- It assumes the Queue's balance as a required field.
balQueue:add( {"look", function () echo( "I looked!") end} )

-- Fairly straightforward, we just throw the table into a variable before passing it to add().
action = {code = "flex muscles", consumed = "my_system.balances.balance", required = "my_system.balances.equilibrium"}
balQueue:add( action )
Having added a number of actions to our Queue, we just need to make it do its thing.
Code: [show] | [select all] lua
balQueue:act()
The Queue will then execute every action in its list that does not consume a balance. In our case, the list would be:
  • "diagnose"
  • function () echo( "This is a test echo from balQueue.\n" ) end
  • {"look",
  • function () echo( "I looked!") end}
As you can see, it skipped one action that consumed a balance. Having executed everything that doesn't consume, it will go back and execute the first action that does. It then creates a tempTimer that will check the balance variable in .5 seconds. If that variable is false, it reinserts the attempted action back into the Queue as the first action, and calls itself. This means, if your system does not set the balance variable to false properly, the Queue will repeatedly try to execute that action. QeMistry doesn't change the variable itself; it assumes your system will handle that.

Also, to execute another consumed action after the first was successful, you must call act() again. I imagine this would be called when the Queue's balance is returned.

Hopefully this makes everything a little clearer. Let me know if you have further questions.

User avatar
keneanung
Site Admin
Posts: 94
Joined: Mon Mar 21, 2011 9:36 am
Discord: keneanung#2803

Re: QeMistry Queue Manager

Post by keneanung »

Is there any way to make it not execute all things that don't require balance? So you will actually do the things in the order you put it in?

User avatar
Oneymus
Posts: 321
Joined: Thu Sep 17, 2009 5:24 am

Re: QeMistry Queue Manager

Post by Oneymus »

At the moment, no. I can add that easily enough, though. Will update soon as I'm home.

User avatar
Oneymus
Posts: 321
Joined: Thu Sep 17, 2009 5:24 am

Re: QeMistry Queue Manager

Post by Oneymus »

Original post updated with the new usage guide and package.

Please post any feedback here. Bugs are nice; ideas for more options would be wonderful.

User avatar
kevutian
Posts: 217
Joined: Fri Aug 20, 2010 8:18 pm
Location: United Kingdom
Contact:

Re: QeMistry Queue Manager

Post by kevutian »

Wrong thread. Thanks.
Last edited by kevutian on Mon Mar 05, 2012 9:54 pm, edited 1 time in total.

User avatar
Oneymus
Posts: 321
Joined: Thu Sep 17, 2009 5:24 am

Re: QeMistry Queue Manager

Post by Oneymus »

Did you post this to the right thread?

Post Reply