-
-
Notifications
You must be signed in to change notification settings - Fork 205
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Count run action finish to call final finish when two run actions are… #1946
Count run action finish to call final finish when two run actions are… #1946
Conversation
Instead of hardcoding
|
both in scene and out scene actions are done on the same single thread right? but not in sequential order? or different idle threads might pick up and execute those actions? if they're on the same thread then i think it should be called sequentially. so, may be just a simple state variable which keeps track of which last action was finished before finishing current action, would be enough. otherwise, if multiple threads might run those in parallel we should make this |
Scene transitions simply use actions, and they run on the main thread, so no multi-threading involved. |
So they should be executed sequentially right? |
I’m not sure how the transitions are stacked and processed but somehow the outScene one was done before the inScene one, leading to position override. |
I thought about adding a method like |
hmm weird those actions are stored in |
Yeah it’s strange
Yeah the finish was called by the outScene action because it was supposed to be the last of the 2 actions called (for all transitions kind) but it’s not the case anymore compared to Cocos2dx; afaik there is no reason one run will end before the other my code is quite simple, being in the MainScene, I just create a GameScene (subclass of ax::Scene) and pushing it using a TransitionSlideInB
|
It would be not hardcoded, but parameterized, generalizing the logic and allowing users to specify the |
I think I understand where you're coming from, but that's not quite how it works. As mentioned earlier, scene transitions use actions. Multiple actions can run at the same time, in parallel, but not in the sense of being parallel threaded, but rather in that they are executing within the same update loop. In the case of scene transitions, whatever operation is being applied to the in and out scenes are happening in parallel, and the If you want to learn more about how actions work, then browse through the |
What warning are you referring to? Also, do you have a video or sample project to clearly show the issue? I'm not quite sure I understand what you meant by "The slide made was going more than the max it should." for The actions applied on the scenes end at a specific duration, and since the order of completion is causing an issue, a possible alternative fix would bet to add a For example, this is the implementation for all slide transitions:
Try changing this:
to this:
|
Just FYI, the reason this scene transition bug has appeared in Axmol is because of a few reasons: 1 - |
This comment in Transaction.cpp, about the "other issue". I think they faced what we encountered but never discovered why.
Adding a 0 delay is not the best to me as it would mean -as you said- that it would trigger at next update, so the transition delay would not be exactly what the user asked for.
Yeah it sounded like that when I looked at how it was done, the issue was already there but it worked by chance. The unordered map explains the order, thanks for info! BTW i updated the PR to have the setWaitForFinishCount() |
ah right now makes sense why for some reason i thought the |
That is not possible, and it wouldn't make sense since the actions are in fact not actually operating on the same node. This really has nothing to do with the
From what I have seen in the action system, it is not easily adaptable to support this. If you go through the different types of actions, especially ones inheriting from |
hmm so i guess the whole |
That's exactly what That being said, if there was |
I guess it just makes sense for current situation, and waiting for |
It is not arbitrary: each transition can override the value to set up the necessary one |
Another solution would be to create a special CallFunc Action that will be added to both sequences and that will manage the count |
I agree. I just disagreed that the solution should be to complicate the transition system itself by adding specialized synchronization system to it. So my proposal was to extend the existing action system by introducing an action that can wait for other action completion. This solution would allow to synchronize actions on different nodes.
I think Sequence::create(
SomeAction::create(),
WaitForAction::create(actionOnAnotherNode1, actionOnAnotherNode2, ...);
SomeOtherAction::create()
); With a CallFunc like thing you'd have to do this inside its callback. Also it would require inserting something into the action list and it would not work in situations when you can only get a pointer to an action like calling some |
I believe the current solution provided by @AlexandreK38 does that, it calls the "special" version of the finish function at the end of both in and out scene actions to maintain the "count"
The 2 is just a lucky number here, that only two node(s) will call the finisth function which maintains the count by chance, this is probably alright for most of the |
Ye that will be also be a good solution overall and by adding some state to Transition i meant usually when you think about Transition, it should have an update function which should first check if |
Just to clarify a few things. Firstly, there is nothing arbitrary about waiting for 2 unconnected actions (or action sequences) to finish, because in the case of scene transitions, there are only 2 scenes that each have their own actions applied. There can be no more than 2 scenes. These scenes are not connected in any way, and neither are there actions. Now, transitions have nothing to do with actions per se. A transition is not an action, it just uses an action. For a lack of a better way to describe this, imagine 2 racing cars that are heading towards a finish line. A celebration even does not start until both cars have crossed the finish line. Those cars not in any way connected to each other, and each has its own action, being to move towards the finish line. There is only one way to determine that both cars have crossed the finish line, and that is by an external observer, not connected to the cars in any way. The racing car itself is not an action, the movement is, and one racing car crossing the finish line has nothing to do with another car crossing it, or what external event happens after they both cross. Does that make sense? |
I strongly feel that everyone involved in this thread, and unfamiliar with the implementation of What is being suggested is not possible in the |
@AlexandreK38 Is this PR complete? With regards to the discussion of the action system, perhaps that should be moved to a separate discussion. |
i get it why 2 is the number, it makes sense only through these discussion tho, i am saying the code isn't quite self explenatory to me(there could be other users like me with less experience) may be we should make comments for future users or may be we could just do something else like: // Transition.h
// private enum class
enum FinishingScenes {
None,
InScene,
OutScene,
Other
}
FinishingScenes _lastFinishedScene = FinishingScenes::None;
// Transition.cpp
void finish(FinishingScenes currentFinishing = FinishingScenes::Other)
{
if (_lastFinishedScene == FinishingScenes::InScene || _lastFinishedScene == FinishingScenes::OutScene)
{
// cleanup
}
_lastFinishedScene = currentFinishing;
}
//child transitions
_outScene->runAction(
Sequence::create(/* custom params */, CallFunc::create(AX_CALLBACK_1(TransitionScene::finish, this, FinishingScenes::OutScene)), nullptr));
_inScene->runAction(
Sequence::create(/* custom params */, CallFunc::create(AX_CALLBACK_1(TransitionScene::finish, this, FinishingScenes::InScene)), nullptr)); if we only care about current situation where the |
Oh right, I totally forgot that. :(
Not OP, but I think it is ready to be merged. @IamSanjid: your example does not work, because |
@rh101 for me it is complete 🙏 At first IamSanjid idea may be better to explain what we do, but adding the scene param (and for example null when we don’t need to wait for several actions to finish or an enum using bitwise for flags and a setter similar to the setWaitFinishCount) isn’t simplifying what we do now |
The current changes in the PR are all that is required to fix the issue, and there is no need to over-engineer it; the implementation is both simple and very clear as to its purpose. |
if the |
That is not correct, and there seems to be some misunderstanding regarding how the scene transitions work. There are 2 separate nodes, each with their own actions applied. If you read through the code, you will quickly see that the actions are applied to the nodes at the same time, so the actions are running at the same time. They actions on one node are in no way linked to the actions of the other node. The order of actions is in not sequential between the 2 nodes (in and out scenes). The finish condition is when the actions on both nodes are complete. The problem, and the initial reason for this PR by the OP, is that there is no way to control the order of completion of the actions, and there is no way for the order of completion to be determined. All that can be done is for the end of each action to somehow flag that it is complete, and once both are complete, then the finish condition is met. There is absolutely nothing wrong or confusing about the implementation made in this PR; it's quite literally a simple counter to track the completion of the transition sequence, and quite frankly, I do not see how it can be any simpler than that. |
I don't get it what my example is doing wrong part? actions are executed simultaneously but not by different thread, my example doesn't care about order, it doesn't matter whether |
Sorry, you're correct, I went through the code sample you provided again, and now I understand what it is doing. Yes, that would work, but, and this is just my opinion, it is not a simpler solution, nor is it easier to understand, than the solution implemented in this PR. |
yeah the first misunderstanding by both @smilediver and you made it clear it's really not simpler or clearer, i don't know i just like to write code in more verbose way i guess, whenever i see something like |
btw about the |
I never tried tbh, but we could give nullptr as param anyway. That was just an idea, I’m not gonna do this 🙂 About having many |
That is not always the case. It can be 1 as well, such as for EDIT: Never-mind, I see that |
I think we're getting too fixated on this issue. We all agree that the fix could be improved with the right tools, but the tools are not available right now and current fix is ok. Let's just merge it. :) |
Yeah let’s merge then 👍 |
Huh, our custom scene transition class that we wrote for our game inherits from axmol::TransitionScene, but we've never run into this issue with ordering (or if we have the issues have been so minor that we never noticed anything wrong). Though now that I'm looking at the code I can see why. We only ever use a single action for the custom TransitionScene class itself, as well as a Spine Skeleton with some animations. |
@halx99 sorry but did you forget to merge? |
Describe your changes
Hi,
After migrating from Cocos2d, I discovered that transition animations were not working properly, like
TransitionSlideInB
for example. The slide made was going more than the max it should.After digging into this and compare with Cocos2d; I found out that the the inScene/outScene run actions were done in the opposite order leading to override the position.
When there is 2 run actions performed in parallel, the order should not matter (maybe that why there is a warning about issues at top of the files by Cocos2d authors)
This is my proposal to fix this issue: call the finish only when both actions are done.