Allow registering custom data for triggers
This allows easier handling of e.g. range triggers calling into the same function. The original trigger data is also forwarded for convenience. Differential Revision: https://code.wildfiregames.com/D3904 This was SVN commit r25413.
This commit is contained in:
parent
f653541e2c
commit
8f8996e338
@ -76,6 +76,7 @@ Trigger.prototype.GetTriggerPoints = function(ref)
|
|||||||
* @param {string} name - Name of the trigger.
|
* @param {string} name - Name of the trigger.
|
||||||
* If no action is specified in triggerData, the action will be the trigger name.
|
* If no action is specified in triggerData, the action will be the trigger name.
|
||||||
* @param {Object} triggerData - f.e. enabled or not, delay for timers, range for range triggers.
|
* @param {Object} triggerData - f.e. enabled or not, delay for timers, range for range triggers.
|
||||||
|
* @param {Object} customData - User-defined data that will be forwarded to the action.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* triggerData = { enabled: true, interval: 1000, delay: 500 }
|
* triggerData = { enabled: true, interval: 1000, delay: 500 }
|
||||||
@ -91,7 +92,7 @@ Trigger.prototype.GetTriggerPoints = function(ref)
|
|||||||
* maxRange = -1 * Maximum range for the query (-1 = no maximum)
|
* maxRange = -1 * Maximum range for the query (-1 = no maximum)
|
||||||
* requiredComponent = 0 * Required component id the entities will have
|
* requiredComponent = 0 * Required component id the entities will have
|
||||||
*/
|
*/
|
||||||
Trigger.prototype.RegisterTrigger = function(event, name, triggerData)
|
Trigger.prototype.RegisterTrigger = function(event, name, triggerData, customData = undefined)
|
||||||
{
|
{
|
||||||
if (!this[event])
|
if (!this[event])
|
||||||
{
|
{
|
||||||
@ -110,7 +111,7 @@ Trigger.prototype.RegisterTrigger = function(event, name, triggerData)
|
|||||||
if (!triggerData.action)
|
if (!triggerData.action)
|
||||||
triggerData.action = name;
|
triggerData.action = name;
|
||||||
|
|
||||||
this[event][name] = triggerData;
|
this[event][name] = { "triggerData": triggerData, "customData": customData };
|
||||||
|
|
||||||
// setup range query
|
// setup range query
|
||||||
if (event == "OnRange")
|
if (event == "OnRange")
|
||||||
@ -141,90 +142,70 @@ Trigger.prototype.DisableTrigger = function(event, name)
|
|||||||
{
|
{
|
||||||
if (!this[event][name])
|
if (!this[event][name])
|
||||||
{
|
{
|
||||||
warn("Trigger.js: Disabling unknown trigger");
|
warn("Trigger.js: Disabling unknown trigger " + name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let data = this[event][name];
|
|
||||||
|
let triggerData = this[event][name].triggerData;
|
||||||
// special casing interval and range triggers for performance
|
// special casing interval and range triggers for performance
|
||||||
if (event == "OnInterval")
|
if (event == "OnInterval")
|
||||||
{
|
{
|
||||||
if (!data.timer) // don't disable it a second time
|
if (!triggerData.timer) // don't disable it a second time
|
||||||
return;
|
return;
|
||||||
let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
|
let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
|
||||||
cmpTimer.CancelTimer(data.timer);
|
cmpTimer.CancelTimer(triggerData.timer);
|
||||||
data.timer = null;
|
triggerData.timer = null;
|
||||||
}
|
}
|
||||||
else if (event == "OnRange")
|
else if (event == "OnRange")
|
||||||
{
|
{
|
||||||
if (!data.queries)
|
if (!triggerData.queries)
|
||||||
{
|
{
|
||||||
warn("Trigger.js: Range query wasn't set up before trying to disable it.");
|
warn("Trigger.js: Range query wasn't set up before trying to disable it.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
|
let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
|
||||||
for (let query of data.queries)
|
for (let query of triggerData.queries)
|
||||||
cmpRangeManager.DisableActiveQuery(query);
|
cmpRangeManager.DisableActiveQuery(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
data.enabled = false;
|
triggerData.enabled = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
Trigger.prototype.EnableTrigger = function(event, name)
|
Trigger.prototype.EnableTrigger = function(event, name)
|
||||||
{
|
{
|
||||||
if (!this[event][name])
|
if (!this[event][name])
|
||||||
{
|
{
|
||||||
warn("Trigger.js: Enabling unknown trigger");
|
warn("Trigger.js: Enabling unknown trigger " + name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let data = this[event][name];
|
let triggerData = this[event][name].triggerData;
|
||||||
// special casing interval and range triggers for performance
|
// special casing interval and range triggers for performance
|
||||||
if (event == "OnInterval")
|
if (event == "OnInterval")
|
||||||
{
|
{
|
||||||
if (data.timer) // don't enable it a second time
|
if (triggerData.timer) // don't enable it a second time
|
||||||
return;
|
return;
|
||||||
if (!data.interval)
|
if (!triggerData.interval)
|
||||||
{
|
{
|
||||||
warn("Trigger.js: An interval trigger should have an intervel in its data");
|
warn("Trigger.js: An interval trigger should have an intervel in its data");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
|
let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
|
||||||
data.timer = cmpTimer.SetInterval(this.entity, IID_Trigger, "DoAction",
|
triggerData.timer = cmpTimer.SetInterval(this.entity, IID_Trigger, "DoAction",
|
||||||
data.delay || 0, data.interval, { "name": name });
|
triggerData.delay || 0, triggerData.interval, { "name": name });
|
||||||
}
|
}
|
||||||
else if (event == "OnRange")
|
else if (event == "OnRange")
|
||||||
{
|
{
|
||||||
if (!data.queries)
|
if (!triggerData.queries)
|
||||||
{
|
{
|
||||||
warn("Trigger.js: Range query wasn't set up before");
|
warn("Trigger.js: Range query wasn't set up before");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
|
let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
|
||||||
for (let query of data.queries)
|
for (let query of triggerData.queries)
|
||||||
cmpRangeManager.EnableActiveQuery(query);
|
cmpRangeManager.EnableActiveQuery(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
data.enabled = true;
|
triggerData.enabled = true;
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function executes the actions bound to the events.
|
|
||||||
* It's either called directlty from other simulation scripts,
|
|
||||||
* or from message listeners in this file
|
|
||||||
*
|
|
||||||
* @param {string} event - One of eventNames
|
|
||||||
* @param {Object} data - will be passed to the actions
|
|
||||||
*/
|
|
||||||
Trigger.prototype.CallEvent = function(event, data)
|
|
||||||
{
|
|
||||||
if (!this[event])
|
|
||||||
{
|
|
||||||
warn("Trigger.js: Unknown trigger event called:\"" + event + "\".");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let name in this[event])
|
|
||||||
if (this[event][name].enabled)
|
|
||||||
this.DoAction({ "action": this[event][name].action, "data": data });
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Trigger.prototype.OnGlobalInitGame = function(msg)
|
Trigger.prototype.OnGlobalInitGame = function(msg)
|
||||||
@ -298,15 +279,15 @@ Trigger.prototype.OnGlobalDiplomacyChanged = function(msg)
|
|||||||
*
|
*
|
||||||
* @param {number} time - Delay in milliseconds.
|
* @param {number} time - Delay in milliseconds.
|
||||||
* @param {string} action - Name of the action function.
|
* @param {string} action - Name of the action function.
|
||||||
* @param {Object} data - Arbitrary object that will be passed to the action function.
|
* @param {Object} eventData - Arbitrary object that will be passed to the action function.
|
||||||
* @return {number} The ID of the timer, so it can be stopped later.
|
* @return {number} The ID of the timer, so it can be stopped later.
|
||||||
*/
|
*/
|
||||||
Trigger.prototype.DoAfterDelay = function(time, action, data)
|
Trigger.prototype.DoAfterDelay = function(time, action, eventData)
|
||||||
{
|
{
|
||||||
let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
|
let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
|
||||||
return cmpTimer.SetTimeout(SYSTEM_ENTITY, IID_Trigger, "DoAction", time, {
|
return cmpTimer.SetTimeout(SYSTEM_ENTITY, IID_Trigger, "DoAction", time, {
|
||||||
"action": action,
|
"action": action,
|
||||||
"data": data
|
"eventData": eventData
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -315,27 +296,78 @@ Trigger.prototype.DoAfterDelay = function(time, action, data)
|
|||||||
*
|
*
|
||||||
* @param {number} interval - Interval in milleseconds between consecutive calls.
|
* @param {number} interval - Interval in milleseconds between consecutive calls.
|
||||||
* @param {string} action - Name of the action function.
|
* @param {string} action - Name of the action function.
|
||||||
* @param {Object} data - Arbitrary object that will be passed to the action function.
|
* @param {Object} eventData - Arbitrary object that will be passed to the action function.
|
||||||
* @param {number} [start] - Optional initial delay in milleseconds before starting the calls.
|
* @param {number} [start] - Optional initial delay in milleseconds before starting the calls.
|
||||||
* If not given, interval will be used.
|
* If not given, interval will be used.
|
||||||
* @return {number} the ID of the timer, so it can be stopped later.
|
* @return {number} the ID of the timer, so it can be stopped later.
|
||||||
*/
|
*/
|
||||||
Trigger.prototype.DoRepeatedly = function(time, action, data, start)
|
Trigger.prototype.DoRepeatedly = function(time, action, eventData, start)
|
||||||
{
|
{
|
||||||
let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
|
let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
|
||||||
return cmpTimer.SetInterval(SYSTEM_ENTITY, IID_Trigger, "DoAction", start !== undefined ? start : time, time, {
|
return cmpTimer.SetInterval(SYSTEM_ENTITY, IID_Trigger, "DoAction", start !== undefined ? start : time, time, {
|
||||||
"action": action,
|
"action": action,
|
||||||
"data": data
|
"eventData": eventData
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by the trigger listeners to exucute the actual action. Including sanity checks.
|
* This function executes the actions bound to the events.
|
||||||
|
* It's either called directlty from other simulation scripts,
|
||||||
|
* or from message listeners in this file
|
||||||
|
*
|
||||||
|
* @param {string} event - One of eventNames
|
||||||
|
* @param {Object} data - will be passed to the actions
|
||||||
|
*/
|
||||||
|
Trigger.prototype.CallEvent = function(event, eventData)
|
||||||
|
{
|
||||||
|
if (!this[event])
|
||||||
|
{
|
||||||
|
warn("Trigger.js: Unknown trigger event called:\"" + event + "\".");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let name in this[event])
|
||||||
|
if (this[event][name].triggerData.enabled)
|
||||||
|
this.DoAction({
|
||||||
|
"action": this[event][name].triggerData.action,
|
||||||
|
"eventData": eventData,
|
||||||
|
"customData": this[event][name].customData,
|
||||||
|
"triggerData": this[event][name].triggerData
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call the action method of a trigger with the given event Data.
|
||||||
|
* By default, call the trigger even if it is currently disabled.
|
||||||
|
*/
|
||||||
|
Trigger.prototype.CallTrigger = function(event, name, eventData, evenIfDisabled = true)
|
||||||
|
{
|
||||||
|
if (!this?.[event]?.[name])
|
||||||
|
{
|
||||||
|
warn(`Trigger.js: called a trigger '${name}' for event '${event}' that wasn't found`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!evenIfDisabled && !this[event][name].triggerData.enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.DoAction({
|
||||||
|
"action": this[event][name].triggerData.action,
|
||||||
|
"eventData": eventData,
|
||||||
|
"customData": this[event][name].customData,
|
||||||
|
"triggerData": this[event][name].triggerData
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by the trigger listeners to execute the actual action. Including sanity checks.
|
||||||
|
* Intended for internal use, prefer CallEvent or CallTrigger.
|
||||||
*/
|
*/
|
||||||
Trigger.prototype.DoAction = function(msg)
|
Trigger.prototype.DoAction = function(msg)
|
||||||
{
|
{
|
||||||
if (this[msg.action])
|
if (this[msg.action])
|
||||||
this[msg.action](msg.data || null);
|
this[msg.action](msg?.eventData, msg?.customData, msg?.triggerData);
|
||||||
else
|
else
|
||||||
warn("Trigger.js: called a trigger action '" + msg.action + "' that wasn't found");
|
warn("Trigger.js: called a trigger action '" + msg.action + "' that wasn't found");
|
||||||
};
|
};
|
||||||
|
@ -15,7 +15,7 @@ TriggerPoint.prototype.Init = function()
|
|||||||
cmpTrigger.RegisterTriggerPoint(this.template.Reference, this.entity);
|
cmpTrigger.RegisterTriggerPoint(this.template.Reference, this.entity);
|
||||||
}
|
}
|
||||||
this.currentCollections = {};
|
this.currentCollections = {};
|
||||||
this.actions = {};
|
this.triggers = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
TriggerPoint.prototype.OnDestroy = function()
|
TriggerPoint.prototype.OnDestroy = function()
|
||||||
@ -28,7 +28,7 @@ TriggerPoint.prototype.OnDestroy = function()
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param action Name of the action function defined under Trigger
|
* @param name Name of the trigger.
|
||||||
* @param data The data is an object containing information for the range query
|
* @param data The data is an object containing information for the range query
|
||||||
* Some of the data has sendible defaults (mentionned next to the object)
|
* Some of the data has sendible defaults (mentionned next to the object)
|
||||||
* data.players = [1,2,3,...] * list of player ids
|
* data.players = [1,2,3,...] * list of player ids
|
||||||
@ -37,7 +37,7 @@ TriggerPoint.prototype.OnDestroy = function()
|
|||||||
* data.requiredComponent = 0 * Required component id the entities will have
|
* data.requiredComponent = 0 * Required component id the entities will have
|
||||||
* data.enabled = false * If the query is enabled by default
|
* data.enabled = false * If the query is enabled by default
|
||||||
*/
|
*/
|
||||||
TriggerPoint.prototype.RegisterRangeTrigger = function(action, data)
|
TriggerPoint.prototype.RegisterRangeTrigger = function(name, data)
|
||||||
{
|
{
|
||||||
var players = data.players || Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager).GetAllPlayers();
|
var players = data.players || Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager).GetAllPlayers();
|
||||||
var minRange = data.minRange || 0;
|
var minRange = data.minRange || 0;
|
||||||
@ -48,7 +48,7 @@ TriggerPoint.prototype.RegisterRangeTrigger = function(action, data)
|
|||||||
var tag = cmpRangeManager.CreateActiveQuery(this.entity, minRange, maxRange, players, cid, cmpRangeManager.GetEntityFlagMask("normal"), true);
|
var tag = cmpRangeManager.CreateActiveQuery(this.entity, minRange, maxRange, players, cid, cmpRangeManager.GetEntityFlagMask("normal"), true);
|
||||||
|
|
||||||
this.currentCollections[tag] = [];
|
this.currentCollections[tag] = [];
|
||||||
this.actions[tag] = action;
|
this.triggers[tag] = name;
|
||||||
return tag;
|
return tag;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ TriggerPoint.prototype.OnRangeUpdate = function(msg)
|
|||||||
r.added = msg.added;
|
r.added = msg.added;
|
||||||
r.removed = msg.removed;
|
r.removed = msg.removed;
|
||||||
var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger);
|
var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger);
|
||||||
cmpTrigger.DoAction({ "action": this.actions[msg.tag], "data": r });
|
cmpTrigger.CallTrigger("OnRange", this.triggers[msg.tag], r);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user