+1
Under review

Make 'play' have the option to be synchronous.

storycode 8 years ago updated by icahill (Administrator) 8 years ago 5
Calling 'play' causes the called action to execute asynchronously - i.e. the action that contains the play will carry on executing without waiting for the called action to complete.
This is a problem if you are creating a series of objects in a loop in response to a user action. You have no way of knowing when the loop completes.
So if the user action causes the current series of objects to be deleted and new ones created, and it is not possible to tell when the action has completed creating the new objects, the user could trigger the action again before it has completed - causing the objects to be deleted before they have finished being created - which causes the app to crash...

It would be really nice if the 'play' action had a flag to make it synchronous so that it could be used as a way of calling actions in the same way that developer created functions are used in any other language - i.e. reusable chunks of code which may change some global variable or passed in parameter and the calling function/action could then act on the modified variables.
Is this the case if you place the play action as the last action after a sync block?

Here is a admittedly very simple example.


<action name="test">
<sync loop="no" startdelay="0">
<alert message="test"/>
<alert message="test2"/>
</sync>
<play anim="action2" />
</action>
The (simplified) use case is like this:


<action name="handle-user-action">
<if lhs="[var:busy-flag]" operator="eq" rhs="0">
<assign property="var:busy-flag" value="1">
<delete target="existing-panels">
<assign property="var:panel-count" value="0">
<play action="build-panels">
<assign property="var:busy-flag" value="0">
</if>
</action>

<action name="build-panels">
<if lhs="[var:panel-count]" operator="lt" rhs="[datasource:somedata.dataSourceResultCount]">
<sync>
<create class="panels" target="someparent" />
<play action="build-panels" />
</sync>
</if>
</action>


The busy flag gets cleared BEFORE the panels have finished being created. If the user triggers the action again before it completes, the app crashes because it is deleting objects that are still being created.
In your "handle-user-action" action all of the tags within your if statement will run simultaneously unless they are our within a sync block. Especially when play tags are concerned you need to coordinate order of operation.

I might recommend a third action for your assign property="var:busy-flag" value="0" that is only triggered when your build panels action is successful.
In reality there are sync tags around the code. I just left them out of the sample.

Also the looping action 'build-panels' is not doing the creation directly but rather is alternately calling different actions which are doing the creation.

I would really like to clear the flag when creation is complete, which is pretty hard to do when calling a cascading series of actions.
would it be possible for you to email me the wire file? I would like to see a complete picture of the issue.

I am sure there is a way to accomplish what you are requesting, have you tried adding a delay to your play tags? This should work as it extends <set>.