Author Topic: [Resource] SimObject::call and SimGroup::chainMethodCall (v2)  (Read 2254 times)

These functions are for dynamically and recursively calling methods on objects.

Code: (SimObject::call) [Select]
function SimObject::call(%this,%method,%v0,%v1,%v2,%v3,%v4,%v5,%v6,%v7,%v8,%v9,%v10,%v11,%v12,%v13,%v14,%v15,%v16,%v17)
{
%lastNull = -1;
for(%i = 0; %i < 18; %i ++)
{
%a = %v[%i];
if(%a $= "")
{
if(%lastNull < 0)
%lastNull = %i;
continue;
}
else
{
if(%lastNull >= 0)
{
for(%e = %lastNull; %e < %i; %e ++)
{
if(%args !$= "")
%args = %args @ ",";
%args = %args @ "\"\"";
}
%lastNull = -1;
}
if(%args !$= "")
%args = %args @ ",";
%args = %args @ "\"" @ %a @ "\"";
}
}

eval(%this @ "." @ %method @ "(" @ %args @ ");");
}



Example:
Code: [Select]
new scriptObject(test);
$method = "setColor";
$color = 0;
test.call($method, $color);




This function is used to recursively call a method.
Code: (SimGroup::chainMethodCall) [Select]
$ChainBatchSize = 100;
$ChainTimeOut = 10;

function SimGroup::chainMethodCall(%this,%method,%v0,%v1,%v2,%v3,%v4,%v5,%v6,%v7,%v8,%v9,%v10,%v11,%v12,%v13,%v14,%v15,%v16,%v17)
{
%batch = (%this.chain_batchSize $= "" ? $Slayer::Server::ChainBatchSize : %this.chain_batchSize);
%count = %this.getCount();
%index = (%this.chain_index $= "" ? %count - 1 : %this.chain_index);
%endIndex = (%index - %batch < 0 ? 0 : %index - %batch);

for(%i = %index; %i >= %endIndex; %i --)
{
%obj = %this.getObject(%i);
%obj.call(%method,%v0,%v1,%v2,%v3,%v4,%v5,%v6,%v7,%v8,%v9,%v10,%v11,%v12,%v13,%v14,%v15,%v16,%v17);
}
%this.chain_index = %endIndex - 1;
if(%this.chain_index <= 0)
{
if(isFunction(%this,%this.chain_callback))
%this.call(%this.chain_callback);
%this.chain_index = "";
%this.chain_batchSize = "";
%this.chain_timeOut = "";
%this.chain_callback = "";
}
else
{
cancel(%this.chain_schedule);
%time = (%this.chain_timeOut $= "" ? $Slayer::Server::ChainTimeOut : %this.chain_timeOut);
%this.chain_schedule = %this.schedule(%time,"chainMethodCall",%method,%v0,%v1,%v2,%v3,%v4,%v5,%v6,%v7,%v8,%v9,%v10,%v11,%v12,%v13,%v14,%v15,%v16,%v17);
}
}
Requires SimObject::call.



Example:
Code: [Select]
brickgroup_11902.chain_batchSize = 100; //this is optional
brickgroup_11902.chain_timeOut = 10; //this is optional
brickgroup_11902.chain_callback = "myCallback"; //this is optional - when the recursive method finishes, brickgroup_11902::myCallback(%this) will be called.
brickgroup_11902.chainMethodCall("setColor", 5);




Change Log (v1 to v2)
  • Now begins at the top of the list (rather than bottom, 0), which prevents problems when deleting objects.
  • Fixed bug where objects at the beginning/end of batch had method called twice.
« Last Edit: July 20, 2013, 08:01:32 PM by Greek2me »

Code: (SimObject::call) [Select]
function SimObject::call(%this,%method,%v0,%v1,%v2,%v3,%v4,%v5,%v6,%v7,%v8,%v9,%v10,%v11,%v12,%v13,%v14,%v15,%v16,%v17)
{
%lastNull = -1;
for(%i = 0; %i < 18; %i ++)
{
%a = %v[%i];
if(%a $= "")
{
if(%lastNull < 0)
%lastNull = %i;
continue;
}
else
{
if(%lastNull >= 0)
{
for(%e = %lastNull; %e < %i; %e ++)
{
if(%args !$= "")
%args = %args @ ",";
%args = %args @ "\"\"";
}
%lastNull = -1;
}
if(%args !$= "")
%args = %args @ ",";
%args = %args @ "\"" @ %a @ "\"";
}
}

eval(%this @ "." @ %method @ "(" @ %args @ ");");
}

Dear god, why? Just do this:

eval("%this." @ %method @ "(%v0,%v1,%v2,%v3,%v4,%v5,%v6,%v7,%v8,%v9,%v10,%v11,%v12,%v13,%v14,%v15,%v16,%v17);");

So... Would the chainMethodCall be a better solution for THIS?

The first one I don't really have a use for, but the chainMethodCall sounds useful.

Dear god, why? Just do this:

eval("%this." @ %method @ "(%v0,%v1,%v2,%v3,%v4,%v5,%v6,%v7,%v8,%v9,%v10,%v11,%v12,%v13,%v14,%v15,%v16,%v17);");

There is actually a very good reason. That's what I did originally, but it doesn't work. Default methods, like setColor, say that you have the wrong number of arguments when you do that. The unused parameters are considered to be "" rather than null by the engine, and it causes an error.

So... Would the chainMethodCall be a better solution for THIS?
Yes.

The first one I don't really have a use for, but the chainMethodCall sounds useful.
Keep in mind that first one is required for the second.

Is .chain_timeOut in milliseconds or seconds?

You should add an option to add variables into the callback.

Is .chain_timeOut in milliseconds or seconds?

You should add an option to add variables into the callback.
It's in milliseconds.

You can just set any needed variables as fields on the object.