On Sun, Oct 18, 2015 at 3:22 AM, Daniel Gillet <[email protected]>
wrote:
> Hi,
>
> Thanks for your comments and sorry for the delay. I was very busy.
>
Np problem, I wasn't exactly fast to answer
>
> In order to fix the memory leak with Scenes, I think it would make sense
> to make it happen in the _set_scene method of the director. As you
> explained, this is the contract which the director enforces.
>
> Regarding the on_enter method called twice, I was thinking that it might
> be useful to people to know when the Transition Scene is completed.
>
Thats is a related but different problem.
Revisiting the duplication problem, if it is acceptable to start the action
at the first on_enter call a cleaner solution is possible:
- in __init__ put a flag
self.action_started = False
- in on_enter play the action only if the flag is False and set the flag
to True
That will work even when playing multiple transitions
> Of course, as you suggested, we can always check if the director scene is
> a TransitionScene.
>
But to me, this feels sort of hacky.
>
I'm sure it can fail with the right combination of transition type,
combination of transitions in a row, cases when theres an initial
transition, then play, then push-pop with transitions.
The multiple possible use cases suggest that the user must be explicit in
what he wants to accomplish. Combined with parts of your ideas a possible
schema to get transitions notification can look as (rough sketch):
- a transition (or the last of a chain of transitions) should override the
finish method by adding as last line
dst.send_event('transition_yyy_ended')
- the dst scene should be an event dispatcher, with a send_event that
publishes the event
- layers interested in that event had registered in their on_enter method
(notice is an dst scene event, so no need for the layer to know about the
transition scene instance)
- notice each transition of interest can have its own handler
- if we want more integration with cocos, a kw-param 'end_message=None'
can be added to TransitionScene.__init__ , if None no call is done, else a
call with the message value is done
Not sure if its worth the added complexity in Scene. In a concrete case, I
would use blinker to publish that event (no need to know the emitter to
register) and be done with that.
> I was thinking about other solutions, but I couldn't find anything really
> great. So I guess what you suggested is the cleaner way. I'll still give
> some of my ideas, just in case ...
>
> One idea was to register an event for TransitionScenes that they would
> broadcast when they finish the transition. But Layers interested to know
> when their Scene are finished doing the transition need to push a handler
> function for that event, which means that the Layer needs to know about the
> TransitionScene, which is probably not a good idea.
>
> Another idea was to implement another method to all cocosnodes which would
> be called by a TransitionScene when the transition is finished. So let's
> say that all cocosnodes had a on_transition_finished method. The
> Transition Scene, in its finished method, would call
> dst.on_transition_finished(). And obviously the default implementation is
> just to pass the message down to the cocosnode children.
>
> def on_transition_finished(self):
> for c in self.get_children():
> c.on_transition_finished()
>
> So a CocosNode interested in this, could overload this method to do
> something appropriately.
>
> But this adds another method to CocosNodes which is only used by
> SceneTransitions. So again, not something optimal.
>
>
> As we're talking about the director, and changing scenes, there is one
> more thing I wanted to address. Say we are in a scene and we *push* a new
> scene. So the old scene is placed on the stack. Say from this new scene,
> instead of poping it, we want to replace it with another scene. Currently
> this would leave the old scene still on the stack, which might be what we
> want, but maybe not. Maybe we just wanted to get rid of all this stack of
> scenes and transition to a brand new scene with a clean stack.
>
> The question is: what is the contract with the director when we change
> scene, regarding the stack? I could imagine a keyword argument to
> director.replace which would allow the user to wipe out any scenes from
> the stack. Something like def replace(self, scene, clean_stack=False)
>
When thinking to augment the API I would consider
- It serves a wide percentage of use cases ?
- A user will find hard to write equivalent functionality with the old
api ?
I would estimate that the percentage is from non-majority to low,
Given that the user should know director operates as stack, and that pop
and replace are visible and surely familiar, he/she can probably write
def replace_entire_director_stack(new_scene):
while len(director.scene_stack)>1:
director.pop()
director.replace(new_scene)
So I think the feature scores too low to be done.
> I will open a new issue on Github for the memory leak. And I'll wait for
> your comments regarding the replace method.
>
> Daniel.
>
> Le samedi 10 octobre 2015 10:25:28 UTC+2, Daniel Gillet a écrit :
>>
>> Hello,
>>
>> I see some problems with the Scenes transitions. First here is what I'm
>> trying to achieve. Imagine a Layer (let's call is static) in a scene. You
>> can transition to another scene with another layer (let's call it action).
>> This action layer has some actions that should be run when the layer comes
>> into play.
>>
>> So I thought I would launch my action in the `on_enter` method. But with
>> the scenes.transitions, it turns out that when creating the scene for the
>> transition, the action layer gets its `on_enter` method called. So it
>> starts doing its thing while the scenes are transitioning. When the
>> transition is done, the director replace the transition scene with the new
>> scene containing our action layer. So its `on_enter` gets called again!
>>
>> Here is a quick demo. You can go from scene 1 to 2 with or without
>> transition. Notice that without transition the label jumps twice while
>> shaking a bit. If we use a transition, it appears while already jumping and
>> jumps more than twice (because of the second call to `on_enter`).
>>
>> See code here: https://gist.github.com/dangillet/cbd23d5ec4162e960eff
>>
>> Also I think there is a memory leak! When the transition is completed, if
>> you look at the new scene (containing the action layer), you will notice
>> that it still has a parent (a scene) which has also a parent (the
>> FadeTransition scene) ! Indeed, when the transition finished in
>> cocos/director.py we call `director.replace(dst)` but we never delete the
>> `self.parent` attribute.
>>
>> Dan.
>>
> --
> You received this message because you are subscribed to the Google Groups
> "cocos2d discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at http://groups.google.com/group/cocos-discuss.
> For more options, visit https://groups.google.com/d/optout.
>
--
You received this message because you are subscribed to the Google Groups
"cocos2d discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/cocos-discuss.
For more options, visit https://groups.google.com/d/optout.