tag:blogger.com,1999:blog-44970923581977041372024-03-08T15:03:32.615+08:00- Endless loop - Development notes of Construct 2's pluginsHuahttp://www.blogger.com/profile/16614422234239844611noreply@blogger.comBlogger17125tag:blogger.com,1999:blog-4497092358197704137.post-24645526851992137252016-02-22T11:32:00.001+08:002016-02-22T11:36:44.600+08:00Destroy children objects when parent object destroyed"object.onDestroy"will be called while object is destroyed by "system action: destroy". But other object could not be destroyed under this function body -<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">instanceProto.onDestroy = function ()</span><br />
<span style="font-family: "Courier New",Courier,monospace;">{ </span><br />
<span style="font-family: "Courier New",Courier,monospace;"> this.runtime.DestroyInstance(other_object);</span><br />
<span style="font-family: "Courier New",Courier,monospace;">};</span><br />
<br />
other_object will not be destroyed.<br />
<br />
A solution to destroy other objects in this case is overwriting the "Destroy" function -<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">pluginProto.onCreate = function ()</span><br />
<span style="font-family: "Courier New",Courier,monospace;">{</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> pluginProto.acts.Destroy = function ()</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> {</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> this.runtime.DestroyInstance(this); // destroy this objet</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> this.runtime.DestroyInstance(other_object); // destroy other object</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> }; </span><br />
<span style="font-family: "Courier New",Courier,monospace;">};</span><br />
<br />
Reference - https://github.com/rexrainbow/C2Plugins/blob/master/plugins/rex_listCtrl/runtime.js#L18 Huahttp://www.blogger.com/profile/16614422234239844611noreply@blogger.com0tag:blogger.com,1999:blog-4497092358197704137.post-69915995416321303162015-03-10T23:50:00.002+08:002015-03-11T11:43:14.819+08:00Override common ACEs of objectpluginProto.onCreate = function ()<br />
{<br />
// Override the 'set width' action<br />
pluginProto.acts.SetWidth = function (w)<br />
{<br />
if (this.width !== w)<br />
{<br />
this.width = w;<br />
this.text_changed = true; // also recalculate text wrapping<br />
this.set_bbox_changed();<br />
}<br />
};<br />
<br />
See the official text plugin.<br />
The common ACEs could be found in commonace.js Huahttp://www.blogger.com/profile/16614422234239844611noreply@blogger.com0tag:blogger.com,1999:blog-4497092358197704137.post-86843664258367059682014-09-23T14:36:00.000+08:002014-09-23T14:36:44.867+08:00Official function to create an instance<span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;">Official function to </span>create an instance, see system.js, line 1284.</span><br />
<span style="font-family: "Courier New",Courier,monospace;"><br /></span>
<span style="font-family: "Courier New",Courier,monospace;">SysActs.prototype.CreateObject = function (obj, layer, x, y)<br />{<br /> if (!layer || !obj)<br /> return;<br /><br /> var inst = this.runtime.createInstance(obj, layer, x, y);<br /> <br /> if (!inst)<br /> return;<br /> <br /> this.runtime.isInOnDestroy++;<br /> <br /> var i, len, s;<br /> this.runtime.trigger(Object.getPrototypeOf(obj.plugin).cnds.OnCreated, inst);<br /> <br /> if (inst.is_contained)<br /> {<br /> for (i = 0, len = inst.siblings.length; i < len; i++)<br /> {<br /> s = inst.siblings[i];<br /> this.runtime.trigger(Object.getPrototypeOf(s.type.plugin).cnds.OnCreated, s);<br /> }<br /> }<br /> <br /> this.runtime.isInOnDestroy--;<br /><br /> // Pick just this instance<br /> var sol = obj.getCurrentSol();<br /> sol.select_all = false;<br /> sol.instances.length = 1;<br /> sol.instances[0] = inst;<br /> <br /> // Siblings aren't in instance lists yet, pick them manually<br /> if (inst.is_contained)<br /> {<br /> for (i = 0, len = inst.siblings.length; i < len; i++)<br /> {<br /> s = inst.siblings[i];<br /> sol = s.type.getCurrentSol();<br /> sol.select_all = false;<br /> sol.instances.length = 1;<br /> sol.instances[0] = s;<br /> }<br /> }<br />};</span>Huahttp://www.blogger.com/profile/16614422234239844611noreply@blogger.com0tag:blogger.com,1999:blog-4497092358197704137.post-34647936758722082832014-05-21T00:44:00.001+08:002016-02-20T18:22:14.348+08:00Procedure of plugins and event sheet in each tick<ol>
<li>pretick() in plugins</li>
<li>tick() in behaviors</li>
<li>posttick() in behaviors</li>
<li>tick() in plugins</li>
<li>"condition: every tick" in event sheet</li>
<li>tick2() in behaviors </li>
<li>tick2() in plugins</li>
<li>draw() in engine </li>
</ol>
<br />
Reference: preview.js, line 2416, function "logic". <br />
<ol>
</ol>
Huahttp://www.blogger.com/profile/16614422234239844611noreply@blogger.com0tag:blogger.com,1999:blog-4497092358197704137.post-2349194347087267212014-04-26T18:04:00.002+08:002014-04-26T18:05:30.343+08:00Get behavior instancefunction GetThisBehavior(inst)<br />
{<br />
var i, len;<br />
for (i = 0, len = inst.behavior_insts.length; i < len; i++)<br />
{<br />
if (inst.behavior_insts[i] instanceof behaviorProto.Instance)<br />
return inst.behavior_insts[i];<br />
}<br />
return null;<br />
};<br />
<br />
See the official DragnDrop behavior.<br />
"behaviorProto" could be changed to specific behavior.Huahttp://www.blogger.com/profile/16614422234239844611noreply@blogger.com0tag:blogger.com,1999:blog-4497092358197704137.post-86779101086718072342014-03-10T11:06:00.000+08:002014-03-11T11:33:14.487+08:00timescale of objectTo get dt of instance, use<br />
<span style="font-family: "Courier New",Courier,monospace;">var dt = this.runtime.getDt(inst); </span><br />
<br />
But only plugin which has "type" to "world" would have my_timescale property. So my_timescale need to be added manually for other case.<br />
For example:<br />
<span style="font-family: "Courier New",Courier,monospace;">this.my_timescale = -1</span>Huahttp://www.blogger.com/profile/16614422234239844611noreply@blogger.com0tag:blogger.com,1999:blog-4497092358197704137.post-14341233879249921562014-02-24T12:34:00.003+08:002014-02-24T12:34:45.077+08:00Reorder z order of layerStep1. Get layer<br /><span style="font-family: "Courier New",Courier,monospace;">var layer = inst.layer;</span><br />
or<br />
<span style="font-family: "Courier New",Courier,monospace;">var layer = (typeof layerparam == "number")?</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> this.runtime.getLayerByNumber(layerparam):</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> this.runtime.getLayerByName(layerparam);</span><br />
<br />
<br />
Step2. Sort the list layer.instances<br />
<span style="font-family: "Courier New",Courier,monospace;">layer.instances(SORTFN);</span><br />
for example<br />
<span style="font-family: "Courier New",Courier,monospace;">function sortInstanceByZIndex(a, b)<br />{</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> return a.zindex - b.zindex;</span><br />
<span style="font-family: "Courier New",Courier,monospace;">}</span><br />
<br />
Step3. reassign zindex of instances in this layer.<br />
<span style="font-family: "Courier New",Courier,monospace;">layer.zindices_stale = true;</span><br />
<br />
<br />
<a href="https://github.com/rexrainbow/C2_plugins/blob/master/plugins/rex_zSorter/runtime.js" rel="nofollow" target="_blank">Reference</a>Huahttp://www.blogger.com/profile/16614422234239844611noreply@blogger.com0tag:blogger.com,1999:blog-4497092358197704137.post-91518452206117508882014-02-22T11:49:00.002+08:002014-02-22T13:12:53.302+08:00Get timeline instance<span style="font-family: "Courier New",Courier,monospace;">instanceProto._timeline_get = function ()<br /> {<br /> if (this.timeline != null)<br /> return this.timeline;<br /> <br /> assert2(cr.plugins_.Rex_TimeLine, "Scenario: Can not find timeline oject.");<br /> var plugins = this.runtime.types;<br /> var name, inst;<br /> for (name in plugins)<br /> {<br /> inst = plugins[name].instances[0];<br /> if (inst instanceof cr.plugins_.Rex_TimeLine.prototype.Instance)<br /> {<br /> this.timeline = inst;<br /> return this.timeline;<br /> }<br /> }<br /> assert2(this.timeline, "Scenario: Can not find timeline oject.");<br /> return null; </span><br />
<span style="font-family: "Courier New",Courier,monospace;">};</span><br />
<br />
<a href="https://github.com/rexrainbow/C2_plugins/blob/master/plugins/rex_scenario/runtime.js" rel="nofollow" target="_blank">Reference</a>Huahttp://www.blogger.com/profile/16614422234239844611noreply@blogger.com0tag:blogger.com,1999:blog-4497092358197704137.post-76739118394752950042014-02-21T15:28:00.003+08:002014-02-21T16:55:44.362+08:00Create instance<span style="font-family: "Courier New",Courier,monospace;">instanceProto.CreateInst = function (objtype,x,y,_layer)<br /> {</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> var layer = (typeof _layer == "number")?</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> this.runtime.getLayerByNumber(_layer):<br /> (typeof _layer == "string")?</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> this.runtime.getLayerByName(_layer): <br /> _layer;<br /> </span><br />
<span style="font-family: "Courier New",Courier,monospace;"> // call system action: Create instance<br /> cr.system_object.prototype.acts.CreateObject.call(<br /> this.runtime.system,<br /> objtype,<br /> layer,<br /> x,<br /> y<br /> );</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> </span><br />
<span style="font-family: "Courier New",Courier,monospace;"> return objtype.getFirstPicked(); // return the created instance<br /> };</span><br />
<a href="https://github.com/rexrainbow/C2_plugins/blob/master/plugins/rex_nickname/runtime.js" rel="nofollow" target="_blank"><br /></a>
<a href="https://github.com/rexrainbow/C2_plugins/blob/master/plugins/rex_nickname/runtime.js" rel="nofollow" target="_blank">Reference</a>Huahttp://www.blogger.com/profile/16614422234239844611noreply@blogger.com0tag:blogger.com,1999:blog-4497092358197704137.post-2269471780750795822014-02-21T10:39:00.001+08:002014-02-21T12:33:34.471+08:00Get SID from object-type, get object-type from SID<b>G<span style="font-family: inherit;">et SID from object-type</span></b><br />
<span style="font-family: "Courier New",Courier,monospace;">var sid = objtype.sid</span><br />
<br />
<span style="font-family: inherit;"><b>Get object-type from sid</b></span><br />
<span style="font-family: "Courier New",Courier,monospace;">var obktype = this.runtime.getObjectTypeBySid(sid);</span><br />
<br />
It will check the object-types list to find the matched target. Keeping the index of the matched target might increase the performance.<br />
<span style="font-family: "Courier New",Courier,monospace;">var objtypes = this.runtime.types_by_index;</span><br />
<span style="font-family: "Courier New",Courier,monospace;">var t = objtypes[index];</span><br />
<span style="font-family: "Courier New",Courier,monospace;">if ((t != null) && (t.sid === sid)) // find the target</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> return t;</span><br />
<span style="font-family: "Courier New",Courier,monospace;">var i, len=objtypes.length;</span><br />
<span style="font-family: "Courier New",Courier,monospace;">for (i=0; i<len; i++)</span><br />
<span style="font-family: "Courier New",Courier,monospace;">{</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> t = objtypes[i]; </span><br />
<span style="font-family: "Courier New",Courier,monospace;"> if (t.sid === sid) // find the target</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> {</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> index = i; // save the index</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> return t;</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> } </span><br />
<span style="font-family: "Courier New",Courier,monospace;">}</span><br />
<br />
<span style="font-family: inherit;"><a href="https://github.com/rexrainbow/C2_plugins/blob/master/plugins/rex_nickname/runtime.js" rel="nofollow" target="_blank">Reference</a></span>Huahttp://www.blogger.com/profile/16614422234239844611noreply@blogger.com0tag:blogger.com,1999:blog-4497092358197704137.post-46284536638605161602014-02-20T22:42:00.002+08:002014-02-21T10:26:56.971+08:00Get angle and distance between two points<b>Distance </b><br />
<span style="font-family: "Courier New",Courier,monospace;">var distance = cr.distanceTo(px0, py0, px1, py1);</span><br />
<br />
<br />
<b>Angle </b><br />
<span style="font-family: "Courier New",Courier,monospace;">var angle = cr.angleTo(px0, py0, px1, py1); // in <span class="st">radian</span></span><br />
<span class="st"><span style="font-family: "Courier New",Courier,monospace;">angle = cr.to_clamped_degrees(angle); // radian to degree</span></span>Huahttp://www.blogger.com/profile/16614422234239844611noreply@blogger.com0tag:blogger.com,1999:blog-4497092358197704137.post-19220523892287763622014-02-20T22:37:00.001+08:002014-02-20T22:37:22.799+08:00Reuse system action<span style="font-family: "Courier New",Courier,monospace;">cr.system_object.prototype.acts.SetLayerEffectParam.call(</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> this.runtime.system, // this</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> param0,</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> ....</span><br />
<span style="font-family: "Courier New",Courier,monospace;">);</span>Huahttp://www.blogger.com/profile/16614422234239844611noreply@blogger.com0tag:blogger.com,1999:blog-4497092358197704137.post-83866096356064572192014-02-20T22:32:00.001+08:002014-02-20T22:45:16.937+08:00Destroy instance<span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: inherit;"></span> this.runtime.DestroyInstance(inst);</span><br />
<br />
<br />
<b>Callback</b> <br />
This<span style="font-family: inherit;"> method wil</span>l trigger a callback, add the callback by<br />
<span style="font-family: "Courier New",Courier,monospace;">this.myDestroyCallback = function (inst)</span><br />
<span style="font-family: "Courier New",Courier,monospace;">{</span><br />
<span style="font-family: "Courier New",Courier,monospace;">.... </span><br />
<span style="font-family: "Courier New",Courier,monospace;">} <br />this.runtime.addDestroyCallback( this.myDestroyCallback ) </span><br />
<br />
Remove the callback by<br />
<span style="font-family: "Courier New",Courier,monospace;">this.runtime.removeDestroyCallback( this.myDestroyCallback );</span>Huahttp://www.blogger.com/profile/16614422234239844611noreply@blogger.com0tag:blogger.com,1999:blog-4497092358197704137.post-57134374046640708962014-02-20T18:38:00.003+08:002014-02-20T22:08:07.039+08:00Array shallow copy<span style="font-family: "Courier New",Courier,monospace;">cr.shallowAssignArray(to_arr, from_arr);</span>Huahttp://www.blogger.com/profile/16614422234239844611noreply@blogger.com0tag:blogger.com,1999:blog-4497092358197704137.post-23152974315525373982014-02-20T18:36:00.000+08:002014-02-20T22:08:29.564+08:00Function declaration string for eval<span style="font-family: "Courier New",Courier,monospace;">.... </span><br />
<span style="font-family: "Courier New",Courier,monospace;">param = param.replace(re, "\\n"); // replace "\n" to "\\n"</span><br />
<span style="font-family: "Courier New",Courier,monospace;">var code_string = "function(scenario)\{\</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> var MEM = scenario.Mem;\</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> var Call = scenario._getvalue_from_c2fn;\</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> return "+param+"\</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> }";</span><br />
<span style="font-family: "Courier New",Courier,monospace;">_thisArg = this;</span><br />
<span style="font-family: "Courier New",Courier,monospace;">var fn = eval("("+code_string+")");</span><br />
<span style="font-family: "Courier New",Courier,monospace;">param = fn(this);</span><br />
<span style="font-family: "Courier New",Courier,monospace;">....</span><br />
<br />
<a href="https://github.com/rexrainbow/C2_plugins/blob/master/plugins/rex_scenario/runtime.js" rel="nofollow" target="_blank">Reference</a><br />
<br />
<br />
The variable space will be cleaned in this eval , in CocoonJS exporter. Huahttp://www.blogger.com/profile/16614422234239844611noreply@blogger.com0tag:blogger.com,1999:blog-4497092358197704137.post-53610874708073490802014-02-20T18:14:00.001+08:002014-02-21T10:26:30.222+08:00Get UID from instance, get instance from UID<b><span style="font-family: inherit;">Ge<span style="font-family: inherit;">t UID from instanc</span>e</span></b><br />
<span style="font-family: "Courier New",Courier,monospace;">var uid = inst.uid;</span><br />
<br />
<b><span style="font-family: inherit;">Ge<span style="font-family: inherit;">t instance from UID</span></span></b><br />
<span style="font-family: "Courier New",Courier,monospace;">var <span class="nx">uid2inst = function (uid)</span></span><br />
<span style="font-family: "Courier New",Courier,monospace;"><span class="nx">{</span></span><br />
<span style="font-family: "Courier New",Courier,monospace;"><span class="nx"> if (uid == null)</span></span><br />
<span style="font-family: "Courier New",Courier,monospace;"><span class="nx"> return null</span></span><br />
<span style="font-family: "Courier New",Courier,monospace;"><span class="k"> return</span> <span class="k">this</span><span class="p">.</span><span class="nx">runtime</span><span class="p">.</span><span class="nx">getObjectByUID</span><span class="p">(</span><span class="nx">uid</span><span class="p">);</span>
<span class="nx"> </span></span><br />
<span style="font-family: "Courier New",Courier,monospace;"><span class="nx">}</span></span><br />
<span class="nx"><br /></span>
<span class="nx">It will return an instance or null.</span>Huahttp://www.blogger.com/profile/16614422234239844611noreply@blogger.com3tag:blogger.com,1999:blog-4497092358197704137.post-5069818138529392722014-02-20T18:00:00.001+08:002014-03-10T13:10:18.346+08:00Reuse ACE<span style="font-family: inherit;">Reuse action/condition/expression from other plugin.</span><br />
<span style="font-family: "Courier New",Courier,monospace;"><b><br /></b></span>
<span style="font-family: "Courier New",Courier,monospace;"><b>Action </b>cr.plugins_.WebStorage.prototype.acts.StoreLocal.call(webstorage_obj, key, value);</span><br />
<span style="font-family: "Courier New",Courier,monospace;"></span><br />
<span style="font-family: "Courier New",Courier,monospace;"><br /><b>Condition</b><br />cr.plugins_.WebStorage.prototype.cnds.LocalStorageExists.call(webstorage_obj, key);<br /> </span><br />
<span style="font-family: "Courier New",Courier,monospace;"></span><br />
<span style="font-family: "Courier New",Courier,monospace;"><br /><b>Expression</b> </span><br />
<span style="font-family: "Courier New",Courier,monospace;">var fake_ret = {</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> value:0,</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> set_any: function(value){this.value=value;},</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> set_int: function(value){this.value=value;},</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> set_float: function(value){this.value=value;}, </span><br />
<span style="font-family: "Courier New",Courier,monospace;"> set_string: function(value) {this.value=value;}, <br />};<br />cr.plugins_.WebStorage.prototype.exps.LocalValue.call(webstorage_obj, fake_ret, key);<br />return fake_ret.value</span><br />
<br />
<br />
<b><span style="font-family: "Courier New",Courier,monospace;">Get instance</span></b><span class="kd"> </span><br />
<span style="font-family: "Courier New",Courier,monospace;"><span class="kd">var</span> <span class="nx">plugins</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">runtime</span><span class="p">.</span><span class="nx">types</span><span class="p">;</span><span class="kd"> </span></span><br />
<span style="font-family: "Courier New",Courier,monospace;"><span class="kd">var</span> <span class="nx">name</span><span class="p">,</span> <span class="nx">inst</span><span class="p">;<span class="p"><span class="k"> </span></span></span></span><br />
<span style="font-family: "Courier New",Courier,monospace;"><span class="p"><span class="p"><span class="k">for</span> <span class="p">(</span><span class="nx">name</span> <span class="k">in</span> <span class="nx">plugins</span><span class="p">)</span></span></span></span><br />
<span style="font-family: "Courier New",Courier,monospace;"><span class="p"><span class="p"><span class="p">{</span></span></span></span><br />
<span style="font-family: "Courier New",Courier,monospace;"><span class="nx"> inst</span> <span class="o">=</span> <span class="nx">plugins</span><span class="p">[</span><span class="nx">name</span><span class="p">].</span><span class="nx">instances</span><span class="p">[</span><span class="mi">0</span><span class="p">];<span class="k"> </span></span></span><br />
<span style="font-family: "Courier New",Courier,monospace;"><span class="p"><span class="k"> if</span> <span class="p">(</span><span class="nx">inst</span> <span class="k">instanceof</span> <span class="nx">cr</span><span class="p">.</span><span class="nx">plugins_</span><span class="p">.</span></span><span class="p"><span class="p"><span class="nx">WebStorage</span></span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">Instance</span><span class="p">)</span></span></span><br />
<span style="font-family: "Courier New",Courier,monospace;"><span class="p"><span class="p"> {</span></span></span><br />
<span style="font-family: "Courier New",Courier,monospace;"><span class="p"><span class="p"> // get target instance </span></span></span><br />
<span style="font-family: "Courier New",Courier,monospace;"><span class="p"><span class="p"> }</span><span class="p"><span class="p"> </span></span></span></span><br />
<span style="font-family: "Courier New",Courier,monospace;"><span class="p"><span class="p"><span class="p">} </span> </span></span></span><br />
<pre><span class="p"><span class="p"> </span></span></pre>
<pre><span class="p"><span class="p"> </span></span></pre>
<pre><span class="p"><span class="p"><span style="font-family: "Courier New",Courier,monospace;"><a href="https://github.com/rexrainbow/C2_plugins/blob/master/plugins/rex_webstorage_ext/runtime.js">Reference - webstorage extension plugin</a></span></span></span><span style="font-family: "Courier New",Courier,monospace;">
</span></pre>
Huahttp://www.blogger.com/profile/16614422234239844611noreply@blogger.com2