diff --git a/cocos/editor-support/cocostudio/ActionTimeline/CCActionTimelineCache.cpp b/cocos/editor-support/cocostudio/ActionTimeline/CCActionTimelineCache.cpp index 51d29f88d5..043babe6b6 100644 --- a/cocos/editor-support/cocostudio/ActionTimeline/CCActionTimelineCache.cpp +++ b/cocos/editor-support/cocostudio/ActionTimeline/CCActionTimelineCache.cpp @@ -164,6 +164,16 @@ ActionTimeline* ActionTimelineCache::createActionFromJson(const std::string& fil return action->clone(); } +ActionTimeline* ActionTimelineCache::createActionFromContent(const std::string& fileName, const std::string& content) +{ + ActionTimeline* action = _animationActions.at(fileName); + if (action == nullptr) + { + action = loadAnimationActionWithContent(fileName, content); + } + return action->clone(); +} + ActionTimeline* ActionTimelineCache::loadAnimationActionWithFile(const std::string& fileName) { // Read content from file @@ -403,7 +413,7 @@ Frame* ActionTimelineCache::loadZOrderFrame(const rapidjson::Value& json) return frame; } - + ActionTimeline* ActionTimelineCache::createActionWithFlatBuffersFile(const std::string &fileName) { ActionTimeline* action = _animationActions.at(fileName); @@ -414,6 +424,16 @@ ActionTimeline* ActionTimelineCache::createActionWithFlatBuffersFile(const std:: return action->clone(); } +ActionTimeline* ActionTimelineCache::createActionWithDataBuffer(Data data, const std::string &fileName) +{ + ActionTimeline* action = _animationActions.at(fileName); + if (action == NULL) + { + action = loadAnimationWithDataBuffer(data, fileName); + } + return action->clone(); +} + ActionTimeline* ActionTimelineCache::loadAnimationActionWithFlatBuffersFile(const std::string &fileName) { // if already exists an action with filename, then return this action diff --git a/cocos/editor-support/cocostudio/ActionTimeline/CCActionTimelineCache.h b/cocos/editor-support/cocostudio/ActionTimeline/CCActionTimelineCache.h index b4bd6a299a..9d06e545b4 100644 --- a/cocos/editor-support/cocostudio/ActionTimeline/CCActionTimelineCache.h +++ b/cocos/editor-support/cocostudio/ActionTimeline/CCActionTimelineCache.h @@ -78,11 +78,14 @@ public: /** Clone a action with the specified name from the container. */ ActionTimeline* createActionFromJson(const std::string& fileName); + ActionTimeline* createActionFromContent(const std::string& fileName, const std::string& content); ActionTimeline* loadAnimationActionWithFile(const std::string& fileName); ActionTimeline* loadAnimationActionWithContent(const std::string&fileName, const std::string& content); ActionTimeline* createActionWithFlatBuffersFile(const std::string& fileName); + ActionTimeline* createActionWithDataBuffer(cocos2d::Data data, const std::string &fileName); + ActionTimeline* loadAnimationActionWithFlatBuffersFile(const std::string& fileName); ActionTimeline* loadAnimationWithDataBuffer(const cocos2d::Data data, const std::string fileName); diff --git a/cocos/editor-support/cocostudio/ActionTimeline/CSLoader.cpp b/cocos/editor-support/cocostudio/ActionTimeline/CSLoader.cpp index de6ab1fd0d..80c201cc57 100644 --- a/cocos/editor-support/cocostudio/ActionTimeline/CSLoader.cpp +++ b/cocos/editor-support/cocostudio/ActionTimeline/CSLoader.cpp @@ -356,12 +356,12 @@ ActionTimeline* CSLoader::createTimeline(const Data data, const std::string& fil if (suffix == "csb") { - return cache->loadAnimationWithDataBuffer(data, filename); + return cache->createActionWithDataBuffer(data, filename); } else if (suffix == "json" || suffix == "ExportJson") { std::string content((char *)data.getBytes(), data.getSize()); - return cache->loadAnimationActionWithContent(filename, content); + return cache->createActionFromContent(filename, content); } return nullptr; @@ -1016,7 +1016,7 @@ Node* CSLoader::nodeWithFlatBuffers(const flatbuffers::NodeTree *nodetree, const { Data buf = FileUtils::getInstance()->getDataFromFile(filePath); node = createNode(buf, callback); - action = timeline::ActionTimelineCache::getInstance()->loadAnimationWithDataBuffer(buf, filePath); + action = createTimeline(buf, filePath); } else { diff --git a/tests/cpp-tests/Classes/ExtensionsTest/CocoStudioActionTimelineTest/ActionTimelineTestScene.cpp b/tests/cpp-tests/Classes/ExtensionsTest/CocoStudioActionTimelineTest/ActionTimelineTestScene.cpp index 2b335ed6fc..4f14965561 100644 --- a/tests/cpp-tests/Classes/ExtensionsTest/CocoStudioActionTimelineTest/ActionTimelineTestScene.cpp +++ b/tests/cpp-tests/Classes/ExtensionsTest/CocoStudioActionTimelineTest/ActionTimelineTestScene.cpp @@ -27,6 +27,7 @@ CocoStudioActionTimelineTests::CocoStudioActionTimelineTests() ADD_TEST_CASE(TestActionTimelineBlendFuncFrame); ADD_TEST_CASE(TestAnimationClipEndCallBack); ADD_TEST_CASE(TestActionTimelinePlayableFrame); + ADD_TEST_CASE(TestActionTimelineIssueWith2SameActionInOneNode); } CocoStudioActionTimelineTests::~CocoStudioActionTimelineTests() @@ -742,3 +743,21 @@ std::string TestActionTimelinePlayableFrame::title() const { return "Test Action Timeline PlayableFrame\n particle and audio"; } + +void TestActionTimelineIssueWith2SameActionInOneNode::onEnter() +{ + CCFileUtils::getInstance()->addSearchPath("ActionTimeline"); + ActionTimelineBaseTest::onEnter(); + + Node* node = CSLoader::createNode("ani2.csb"); + ActionTimeline* action = CSLoader::createTimeline("ani2.csb"); + node->setPosition(Vec2(150, 100)); + node->runAction(action); + action->gotoFrameAndPlay(0); + this->addChild(node); +} + +std::string TestActionTimelineIssueWith2SameActionInOneNode::title() const +{ + return "Add multi same action in one node issue\n These two actions should play async."; +} \ No newline at end of file diff --git a/tests/cpp-tests/Classes/ExtensionsTest/CocoStudioActionTimelineTest/ActionTimelineTestScene.h b/tests/cpp-tests/Classes/ExtensionsTest/CocoStudioActionTimelineTest/ActionTimelineTestScene.h index 0942f9a426..0a8b8a2cbf 100644 --- a/tests/cpp-tests/Classes/ExtensionsTest/CocoStudioActionTimelineTest/ActionTimelineTestScene.h +++ b/tests/cpp-tests/Classes/ExtensionsTest/CocoStudioActionTimelineTest/ActionTimelineTestScene.h @@ -164,4 +164,14 @@ public: virtual void onEnter() override; virtual std::string title() const override; }; + +class TestActionTimelineIssueWith2SameActionInOneNode : public ActionTimelineBaseTest +{ +public: + CREATE_FUNC(TestActionTimelineIssueWith2SameActionInOneNode); + + virtual void onEnter() override; + virtual std::string title() const override; +}; + #endif // __ANIMATION_SCENE_H__ diff --git a/tests/cpp-tests/Resources/ActionTimeline/ani1.csb b/tests/cpp-tests/Resources/ActionTimeline/ani1.csb new file mode 100644 index 0000000000..c6b95db42a Binary files /dev/null and b/tests/cpp-tests/Resources/ActionTimeline/ani1.csb differ diff --git a/tests/cpp-tests/Resources/ActionTimeline/ani2.csb b/tests/cpp-tests/Resources/ActionTimeline/ani2.csb new file mode 100644 index 0000000000..3c84f7aee7 Binary files /dev/null and b/tests/cpp-tests/Resources/ActionTimeline/ani2.csb differ diff --git a/tools/tolua/cocos2dx_studio.ini b/tools/tolua/cocos2dx_studio.ini index 2e80e9680f..8e68c3d9cd 100644 --- a/tools/tolua/cocos2dx_studio.ini +++ b/tools/tolua/cocos2dx_studio.ini @@ -52,7 +52,7 @@ skip = *::[^visit$ copyWith.* onEnter.* onExit.* ^description$ getObjectType .* ActionNode::[initWithDictionary], ActionObject::[initWithDictionary initWithBinary], BaseData::[copy subtract], - ActionTimelineCache::[getInstance loadActionTimelineFromXML loadAnimationWithDataBuffer], + ActionTimelineCache::[getInstance loadActionTimelineFromXML loadAnimationWithDataBuffer createActionWithDataBuffer], ActionTimeline::[setFrameEventCallFunc] rename_functions = ActionManagerEx::[shareManager=getInstance purgeActionManager=destroyInstance],