- Joined
- Jan 23, 2015
- Messages
- 124
JASS:
//! zinc
library CustomEvent /*
*/ //! novjass
* by Trokkin, Version 1.5 *" http://www.hiveworkshop.com/members/trokkin.243282/ "
****************************************************************************************************
* This snippet is made for purpose of creating custom events and listening to them the most
* efficient and easy way.
*
* Credits to
* AGD for his great advises, which shaped the snippet itself by my hands.
* Bribe for his Table.
*
* To implement the snippet, you only have to copy-paste this code to your map.
****************************************************************************************************
* API:
* struct Event {
*
* $ Set this code to listener of event
* method subscribe(code c)
* $ Unset this code to listener of event
* method unsubscribe(code c)
* $ Clears the entire event from code listeners
* method clear()
*
* $ Two methods working around one boolean that can disable any .fire() on that Event.
* method enable(boolean flag)
* method enabled() -> boolean
* $ You can also use non-private field directly instead of methods.
* boolean isEnabled;
*
* $ Set this trigger to listener of event; remember that codes is ran earlier than triggers.
* method linkTrigger(trigger t)
* // I personally dont recommend using dynamic events with triggers. And triggers overall.
*
* $ Runs event so each registered code will be executed.
* $ Has an ability to attach some data with single run.
* $ (one integer should be enough to attach any other data through arrays/structs)
* method fire(integer data)
* $ Event has two additional fields to use in executed code:
* $ represents current fired event
* public static operator thistype fired() -> Event
* $ represents attached data of event
* public integer data
* /* So basicly you'd want to use */Event.fired.data/* to asquire attached data */
*
* $ no commentaries needed.
* static method create() -> Event
* method destroy()
* // If there are triggers subscribed on it previously, then a shadow of it will remain,
* // preventing from using the same index twice and so linked triggers.
*
* }
*
****************************************************************************************************
//! endnovjass
/************************************************************************************
*
* */ requires /*
* */ Alloc, /* by Sevion
* http://www.hiveworkshop.com/threads/snippet-alloc.192348/
* */ Table /* by Bribe
* http://www.hiveworkshop.com/forums/jass-resources-412/snippet-new-table-188084/
*
* Since it's Zinc, ofc you need JNGP.
*
************************************************************************************/
{
public struct Event[] {
module Alloc;
public integer data;
private {
static real variable = 0.0;
boolean hasLinkedTriggers;
trigger trigger;
Table hash;
}
boolean isEnabled;
method enable(boolean flag) { this.
isEnabled = flag; }
method enabled() -> boolean { return this.isEnabled; }
method register(code c) {
filterfunc filter = Filter(c);
integer i = GetHandleId(filter);
debug { if(hash.triggercondition.has(i)) BJDebugMsg("[CustomEvent] ERROR: tried to add one function twice on event "+I2S(this)+".");}
if(!hash.triggercondition.has(i))
hash.triggercondition[i] = TriggerAddCondition(this.trigger, filter);
filter = null;
}
method unregister(code c) {
integer i = GetHandleId(Filter(c));
debug { if(!hash.triggercondition.has(i)) BJDebugMsg("[CustomEvent] ERROR: tried to remove unadded funciton on event "+I2S(this)+"."); }
if(hash.triggercondition.has(i)) {
TriggerRemoveCondition(this.trigger,hash.triggercondition[i]);
hash.triggercondition.remove(i);
}
}
method linkTrigger(trigger t) {
this.hasLinkedTriggers = true;
TriggerRegisterVariableEvent(t, "s__Event_variable", EQUAL, this);
}
method clear() { TriggerClearConditions(this.trigger); this.hash.flush(); }
static method operator fired() -> thistype { return R2I(thistype.variable); }
method fire(integer data) {
real pTrigger = thistype.variable;
integer pData = this.data;
if(!this.isEnabled) return;
thistype.variable = this + 0.5; // the +0.5 sets registered codes in priority to linked triggers
this.data = data; // while keeping fired() returns always rounded down exact value
TriggerEvaluate(this.trigger); // fire subscribers
thistype.variable = this; // fire listeners
thistype.variable = pTrigger;
this.data = pData;
}
static method create() -> thistype {
thistype this = thistype.allocate();
this.data = 0;
this.hash = Table.create();
this.hasLinkedTriggers = false;
this.isEnabled = true;
if(this.trigger == null) this.trigger = CreateTrigger();
return this;
}
method destroy() {
this.clear();
this.hash.destroy();
this.isEnabled = false;
if(!this.hasLinkedTriggers) this.deallocate();
}
}
}
//! endzinc
JASS:
scope MyScope initializer onInit
globals
Event Timer_Event
Event Kill_Event
trigger first_blood
trigger onKillT
integer time
Table UDex
endglobals
private function annoy takes nothing returns nothing
if(Event.fired.data < 120) then
call BJDebugMsg("It's " + I2S(Event.fired.data) + " seconds of gametime.")
call BJDebugMsg("Sorry, I'm so stupid that I can't count the time normally.")
else
call BJDebugMsg("Oh! It's only one minute passed!")
call Timer_Event.enable(false)
call BJDebugMsg("Now I can't count time any more.")
endif
endfunction
private function FirstBlood takes nothing returns boolean
call BJDebugMsg(GetUnitName(UDex.unit[Event.fired.data]) + " is sooo bad, he died first!")
call DestroyTrigger(first_blood)
return false
endfunction
private function onKill takes nothing returns boolean
set UDex.unit[GetHandleId(GetTriggerUnit())] = GetTriggerUnit()
call Kill_Event.fire(GetHandleId(GetTriggerUnit())) // Doesn't matter how bad is this rly
return false
endfunction
private function onTime takes nothing returns nothing
call Timer_Event.fire(time)
set time = time + 1
endfunction
private function onInit takes nothing returns nothing
// Init sample kill event workaround
set Kill_Event = Event.create()
set onKillT = CreateTrigger()
call TriggerAddCondition(onKillT,Filter(function onKill))
call TriggerRegisterAnyUnitEventBJ(onKillT, EVENT_PLAYER_UNIT_DEATH)
set UDex = Table.create()
// Init sample clock
set Timer_Event = Event.create()
set time = 0
call TimerStart(CreateTimer(), 0.5, true, function onTime)
// Init listeners
set first_blood = CreateTrigger()
call TriggerAddCondition(first_blood,Filter(function FirstBlood))
call Kill_Event.linkTrigger(first_blood)
call Timer_Event.register(function annoy)
endfunction
endscope
Last edited: