SecureStateDriver

__NOTOC__
A SecureStateDriver allows code snippets to execute upon game state changes expressible using macro conditionals.
SecureStateDriver.lua implements two kinds of SecureStateDriver:
* AttributeDriver (formerly StateDriver) securely controls any type of by toggling its visibility or setting customizable attributes
* UnitWatch securely controls a unit frame by toggling its visibility or state-unitexists attribute
Combined with SecureHandlerStateTemplate or SecureUnitButtonTemplate, these SecureStateDrivers faciliate code execution in the RestrictedEnvironment to alter protected values during combat.
== AttributeDriver ==
 RegisterAttributeDriver(frame, attribute, conditional)
 UnregisterAttributeDriver(frame, attribute)
 RegisterStateDriver(frame, state, conditional) -- depreciated
 UnregisterStateDriver(frame, state) -- depreciated
Creates or cancels an AttributeDriver. Frames execute code snippets insecurely using or securely by inheriting SecureHandlerStateTemplate.
The depreciated StateDriver functions forward their arguments to AttributeDriver ones after prepending the second argument with "state-".
; frame : - The AttributeDriver acts on this frame by toggling its visibility or setting its attributes
; attribute : String - Any arbitrary identifier, but converted to lower case with the following results:
:* "state-visibility" causes an AttributeDriver to securely call () when the macro conditional evaluates to "show" or () when it evaluates to "hide"
:* Other values cause an AttributeDriver to securely call (state, result) using the outcome of the macro conditional's evaluation as result
; state : String - Prepended with "state-" and then used similar to attribute (ie. state "visibility" becomes attribute "state-visibility")
; conditional : String - A macro conditional parsable by 
== UnitWatch ==
 RegisterUnitWatch(frame, asState)
 UnregisterUnitWatch(frame, asState)
Creates or cancels a UnitWatch. Frames must inherit SecureUnitButtonTemplate and have an assigned unitId using ("unit", "unitId")
; frame : - The UnitWatch acts on this frame by toggling its visibility or setting its attributes
; asState : Boolean - Controls the behaviour of a UnitWatch with the following results:
:* True causes the UnitWatch to securely call ("state-unitexists", result) using the outcome of the macro conditonal's evaluation as result
:* False causes the UnitWatch to securely call () when the macro conditional evaluates to "show" or () when it evaluates to "hide"
==Examples==
;Showing/hiding a unit frame:
 local frame = CreateFrame("Button", "MyParty1", UIParent, "SecureUnitButtonTemplate")
 frame:SetAttribute("unit", "party1")
 RegisterUnitWatch(frame)
 
 frame:SetPoint("CENTER")
 frame:SetSize(50, 50)
 frame:SetBackdrop({ bgFile = "Interface\\BUTTONS\\WHITE8X8", tile = true, tileSize = 8 })
 frame:SetBackdropColor(1, 0, 0)
The snippet above will display a clickable unit frame for the "party1" unit (consisting solely of a red square in the center of your screen) only when the unit exists.
;Responding to custom states
 local frame = CreateFrame("Frame", "MyStatefulFrame", UIParent, "SecureHandlerStateTemplate")
 RegisterStateDriver(frame, "petstate", "[@pet,noexists] nopet; [@pet,help] mypet; [@pet,harm] mcpet")
 frame:SetAttribute("_onstate-petstate", [[ -- arguments: self, stateid, newstate
 if newstate == "nopet" then
 print("Where are you, kitty?")
 elseif newstate == "mypet" then
 print("Oh hai, kitty!")
 elseif newstate == "mcpet" then
 print("Curse your sudden but inevitable betrayal, kitty!") -- Your pet is hostile to you.
 end
 ]])
;RegisterStateDriver just implements RegisterAttributeDriver
 function RegisterStateDriver(frame, state, conditional)
 return RegisterAttributeDriver(frame, "state-"..state, values);
 end
== Notes ==
* Conditionals are evaluated by SecureStateDriverManager's and handlers:
** Before each new frame, but not faster than STATE_DRIVER_UPDATE_THROTTLE (currently 0.2 sec)
** Immediately upon the following events:
*** 
*** 
*** 
*** 
*** 
*** 
*** 
*** 
*** 
*** 
*** 
*** 
== Patch changes ==
*
*
*
== References ==