From cecb20f8245475666eaa969937689b1486fab8c5 Mon Sep 17 00:00:00 2001 From: James Chen Date: Tue, 21 Jan 2014 17:50:53 +0800 Subject: [PATCH 1/5] issue #3677: Adds EventDispatcher performance test. --- .../project.pbxproj.REMOVED.git-id | 2 +- .../PerformanceEventDispatcher.cpp | 795 ++++++++++++++++++ .../PerformanceEventDispatcher.h | 106 +++ .../PerformanceTest/PerformanceTest.cpp | 4 +- 4 files changed, 905 insertions(+), 2 deletions(-) create mode 100644 samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceEventDispatcher.cpp create mode 100644 samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceEventDispatcher.h diff --git a/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id index 9cba0dacb7..118f1ee7eb 100644 --- a/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -986d41d9721f8079f005999caa9fb0053ea11321 \ No newline at end of file +4f83e9cf42efe5a2a604cf4381c3acd757f0c3ce \ No newline at end of file diff --git a/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceEventDispatcher.cpp b/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceEventDispatcher.cpp new file mode 100644 index 0000000000..f0737e6df5 --- /dev/null +++ b/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceEventDispatcher.cpp @@ -0,0 +1,795 @@ +// +// PerformanceEventDispatcher.cpp +// + +#include "PerformanceEventDispatcher.h" + +#include + +// Enable profiles for this file +#undef CC_PROFILER_DISPLAY_TIMERS +#define CC_PROFILER_DISPLAY_TIMERS() Profiler::getInstance()->displayTimers() +#undef CC_PROFILER_PURGE_ALL +#define CC_PROFILER_PURGE_ALL() Profiler::getInstance()->releaseAllTimers() + +#undef CC_PROFILER_START +#define CC_PROFILER_START(__name__) ProfilingBeginTimingBlock(__name__) +#undef CC_PROFILER_STOP +#define CC_PROFILER_STOP(__name__) ProfilingEndTimingBlock(__name__) +#undef CC_PROFILER_RESET +#define CC_PROFILER_RESET(__name__) ProfilingResetTimingBlock(__name__) + +#undef CC_PROFILER_START_CATEGORY +#define CC_PROFILER_START_CATEGORY(__cat__, __name__) do{ if(__cat__) ProfilingBeginTimingBlock(__name__); } while(0) +#undef CC_PROFILER_STOP_CATEGORY +#define CC_PROFILER_STOP_CATEGORY(__cat__, __name__) do{ if(__cat__) ProfilingEndTimingBlock(__name__); } while(0) +#undef CC_PROFILER_RESET_CATEGORY +#define CC_PROFILER_RESET_CATEGORY(__cat__, __name__) do{ if(__cat__) ProfilingResetTimingBlock(__name__); } while(0) + +#undef CC_PROFILER_START_INSTANCE +#define CC_PROFILER_START_INSTANCE(__id__, __name__) do{ ProfilingBeginTimingBlock( String::createWithFormat("%08X - %s", __id__, __name__)->getCString() ); } while(0) +#undef CC_PROFILER_STOP_INSTANCE +#define CC_PROFILER_STOP_INSTANCE(__id__, __name__) do{ ProfilingEndTimingBlock( String::createWithFormat("%08X - %s", __id__, __name__)->getCString() ); } while(0) +#undef CC_PROFILER_RESET_INSTANCE +#define CC_PROFILER_RESET_INSTANCE(__id__, __name__) do{ ProfilingResetTimingBlock( String::createWithFormat("%08X - %s", __id__, __name__)->getCString() ); } while(0) + +static std::function createFunctions[] = +{ + CL(TouchEventDispatchingPerfTest), + CL(KeyboardEventDispatchingPerfTest), + CL(CustomEventDispatchingPerfTest), +}; + +#define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0])) + +enum { + kTagInfoLayer = 1, + + kTagBase = 20000, +}; + +enum { + kMaxNodes = 15000, + kNodesIncrease = 500, +}; + +static int g_curCase = 0; + +//////////////////////////////////////////////////////// +// +// EventDispatcherBasicLayer +// +//////////////////////////////////////////////////////// + +EventDispatcherBasicLayer::EventDispatcherBasicLayer(bool bControlMenuVisible, int nMaxCases, int nCurCase) +: PerformBasicLayer(bControlMenuVisible, nMaxCases, nCurCase) +{ +} + +void EventDispatcherBasicLayer::showCurrentTest() +{ + int nodes = ((PerformanceEventDispatcherScene*)getParent())->getQuantityOfNodes(); + + auto scene = createFunctions[_curCase](); + + g_curCase = _curCase; + + if (scene) + { + scene->initWithQuantityOfNodes(nodes); + + Director::getInstance()->replaceScene(scene); + } +} + +//////////////////////////////////////////////////////// +// +// PerformanceEventDispatcherScene +// +//////////////////////////////////////////////////////// +void PerformanceEventDispatcherScene::initWithQuantityOfNodes(unsigned int nNodes) +{ + _type = 0; + srand(time(nullptr)); + auto s = Director::getInstance()->getWinSize(); + + // Title + auto label = LabelTTF::create(title().c_str(), "Arial", 40); + addChild(label, 1, TAG_TITLE); + label->setPosition(Point(s.width/2, s.height-32)); + label->setColor(Color3B(255,255,40)); + + // Subtitle + std::string strSubTitle = subtitle(); + if(strSubTitle.length()) + { + auto l = LabelTTF::create(strSubTitle.c_str(), "Thonburi", 16); + addChild(l, 1, TAG_SUBTITLE); + l->setPosition(Point(s.width/2, s.height-80)); + } + + _lastRenderedCount = 0; + _currentQuantityOfNodes = 0; + _quantityOfNodes = nNodes; + + MenuItemFont::setFontSize(65); + auto decrease = MenuItemFont::create(" - ", [&](Object *sender) { + _quantityOfNodes -= kNodesIncrease; + if( _quantityOfNodes < 0 ) + _quantityOfNodes = 0; + + updateQuantityLabel(); + updateQuantityOfNodes(); + updateProfilerName(); + CC_PROFILER_PURGE_ALL(); + srand(0); + }); + decrease->setColor(Color3B(0,200,20)); + _decrease = decrease; + + auto increase = MenuItemFont::create(" + ", [&](Object *sender) { + _quantityOfNodes += kNodesIncrease; + if( _quantityOfNodes > kMaxNodes ) + _quantityOfNodes = kMaxNodes; + + updateQuantityLabel(); + updateQuantityOfNodes(); + updateProfilerName(); + CC_PROFILER_PURGE_ALL(); + srand(0); + }); + increase->setColor(Color3B(0,200,20)); + _increase = increase; + + auto menu = Menu::create(decrease, increase, NULL); + menu->alignItemsHorizontally(); + menu->setPosition(Point(s.width/2, s.height/2+15)); + addChild(menu, 1); + + auto infoLabel = LabelTTF::create("0 listeners", "Marker Felt", 30); + infoLabel->setColor(Color3B(0,200,20)); + infoLabel->setPosition(Point(s.width/2, s.height/2-15)); + addChild(infoLabel, 1, kTagInfoLayer); + + auto menuLayer = new EventDispatcherBasicLayer(true, MAX_LAYER, g_curCase); + addChild(menuLayer); + menuLayer->release(); + + printf("Size of Node: %lu\n", sizeof(Node)); + + int oldFontSize = MenuItemFont::getFontSize(); + MenuItemFont::setFontSize(24); + + Vector toggleItems; + + generateTestFunctions(); + + CCASSERT(!_testFunctions.empty(), "Should not be empty after generate test functions"); + + + for (const auto& f : _testFunctions) + { + toggleItems.pushBack(MenuItemFont::create(f.name)); + } + + auto reset = [this](){ + // Removes all nodes + for (auto& node : _nodes) + { + node->removeFromParent(); + } + + _nodes.clear(); + + // Removes all fixed listeners + for (auto& listener : _fixedPriorityListeners) + { + Director::getInstance()->getEventDispatcher()->removeEventListener(listener); + } + + this->_lastRenderedCount = 0; + }; + + auto toggle = MenuItemToggle::createWithCallback([=](Object* sender){ + auto toggle = static_cast(sender); + this->_type = toggle->getSelectedIndex(); + auto label = static_cast(this->getChildByTag(TAG_SUBTITLE)); + label->setString(StringUtils::format("Test '%s', See console", this->_testFunctions[this->_type].name)); + this->updateProfilerName(); + reset(); + }, toggleItems); + + toggle->setAnchorPoint(Point::ANCHOR_MIDDLE_LEFT); + toggle->setPosition(VisibleRect::left()); + _toggle = toggle; + + auto start = MenuItemFont::create("start", [this](Object* sender){ + auto director = Director::getInstance(); + auto sched = director->getScheduler(); + + CC_PROFILER_PURGE_ALL(); + sched->scheduleSelector(schedule_selector(PerformanceEventDispatcherScene::dumpProfilerInfo), this, 2, false); + + this->unscheduleUpdate(); + this->scheduleUpdate(); + this->_startItem->setEnabled(false); + this->_stopItem->setEnabled(true); + this->_toggle->setEnabled(false); + this->_increase->setEnabled(false); + this->_decrease->setEnabled(false); + }); + start->setAnchorPoint(Point::ANCHOR_MIDDLE_RIGHT); + start->setPosition(VisibleRect::right() + Point(0, 40)); + _startItem = start; + + auto stop = MenuItemFont::create("stop", [=](Object* sender){ + auto director = Director::getInstance(); + auto sched = director->getScheduler(); + + sched->unscheduleSelector(schedule_selector(PerformanceEventDispatcherScene::dumpProfilerInfo), this); + + this->unscheduleUpdate(); + this->_startItem->setEnabled(true); + this->_stopItem->setEnabled(false); + this->_toggle->setEnabled(true); + this->_increase->setEnabled(true); + this->_decrease->setEnabled(true); + + reset(); + }); + + stop->setEnabled(false); + stop->setAnchorPoint(Point::ANCHOR_MIDDLE_RIGHT); + stop->setPosition(VisibleRect::right() + Point(0, -40)); + _stopItem = stop; + + auto menu2 = Menu::create(toggle, start, stop, NULL); + menu2->setPosition(Point::ZERO); + addChild(menu2); + + MenuItemFont::setFontSize(oldFontSize); + + updateQuantityLabel(); + updateQuantityOfNodes(); + updateProfilerName(); +} + +std::string PerformanceEventDispatcherScene::title() const +{ + return "No title"; +} + +std::string PerformanceEventDispatcherScene::subtitle() const +{ + return ""; +} + +void PerformanceEventDispatcherScene::updateQuantityLabel() +{ + if( _quantityOfNodes != _lastRenderedCount ) + { + auto infoLabel = static_cast( getChildByTag(kTagInfoLayer) ); + char str[20] = {0}; + sprintf(str, "%u listeners", _quantityOfNodes); + infoLabel->setString(str); + } +} + +const char * PerformanceEventDispatcherScene::profilerName() +{ + return _profilerName; +} + +void PerformanceEventDispatcherScene::updateProfilerName() +{ + snprintf(_profilerName, sizeof(_profilerName)-1, "%s(%d)", testName(), _quantityOfNodes); +} + +void PerformanceEventDispatcherScene::dumpProfilerInfo(float dt) +{ + CC_PROFILER_DISPLAY_TIMERS(); +} + +void PerformanceEventDispatcherScene::update(float dt) +{ + _testFunctions[_type].func(); +} + +void PerformanceEventDispatcherScene::updateQuantityOfNodes() +{ + _currentQuantityOfNodes = _quantityOfNodes; +} + +const char* PerformanceEventDispatcherScene::testName() +{ + return _testFunctions[_type].name; +} + + +//////////////////////////////////////////////////////// +// +// TouchEventDispatchingPerfTest +// +//////////////////////////////////////////////////////// + +void TouchEventDispatchingPerfTest::generateTestFunctions() +{ + TestFunction testFunctions[] = { + { "OneByOne-scenegraph", [=](){ + auto dispatcher = Director::getInstance()->getEventDispatcher(); + if (_quantityOfNodes != _lastRenderedCount) + { + auto listener = EventListenerTouchOneByOne::create(); + listener->onTouchBegan = [](Touch* touch, Event* event){ + return false; + }; + + listener->onTouchMoved = [](Touch* touch, Event* event){}; + listener->onTouchEnded = [](Touch* touch, Event* event){}; + + // Create new touchable nodes + for (int i = 0; i < this->_quantityOfNodes; ++i) + { + auto node = Node::create(); + node->setTag(1000 + i); + this->addChild(node); + this->_nodes.push_back(node); + dispatcher->addEventListenerWithSceneGraphPriority(listener->clone(), node); + } + + _lastRenderedCount = _quantityOfNodes; + } + + Size size = Director::getInstance()->getWinSize(); + EventTouch touchEvent; + touchEvent.setEventCode(EventTouch::EventCode::BEGAN); + std::vector touches; + + for (int i = 0; i < 4; ++i) + { + Touch* touch = new Touch(); + touch->autorelease(); + touch->setTouchInfo(i, rand() % 200, rand() % 200); + touches.push_back(touch); + } + touchEvent.setTouches(touches); + + CC_PROFILER_START(this->profilerName()); + dispatcher->dispatchEvent(&touchEvent); + CC_PROFILER_STOP(this->profilerName()); + } } , + + { "OneByOne-fixed", [=](){ + auto dispatcher = Director::getInstance()->getEventDispatcher(); + if (_quantityOfNodes != _lastRenderedCount) + { + auto listener = EventListenerTouchOneByOne::create(); + listener->onTouchBegan = [](Touch* touch, Event* event){ + return false; + }; + + listener->onTouchMoved = [](Touch* touch, Event* event){}; + listener->onTouchEnded = [](Touch* touch, Event* event){}; + + for (int i = 0; i < this->_quantityOfNodes; ++i) + { + auto l = listener->clone(); + this->_fixedPriorityListeners.push_back(l); + dispatcher->addEventListenerWithFixedPriority(l, i+1); + } + + _lastRenderedCount = _quantityOfNodes; + } + + Size size = Director::getInstance()->getWinSize(); + EventTouch touchEvent; + touchEvent.setEventCode(EventTouch::EventCode::BEGAN); + std::vector touches; + + for (int i = 0; i < 4; ++i) + { + Touch* touch = new Touch(); + touch->autorelease(); + touch->setTouchInfo(i, rand() % 200, rand() % 200); + touches.push_back(touch); + } + touchEvent.setTouches(touches); + + CC_PROFILER_START(this->profilerName()); + dispatcher->dispatchEvent(&touchEvent); + CC_PROFILER_STOP(this->profilerName()); + } } , + + { "AllAtOnce-scenegraph", [=](){ + auto dispatcher = Director::getInstance()->getEventDispatcher(); + if (_quantityOfNodes != _lastRenderedCount) + { + auto listener = EventListenerTouchAllAtOnce::create(); + listener->onTouchesBegan = [](const std::vector touches, Event* event){}; + listener->onTouchesMoved = [](const std::vector touches, Event* event){}; + listener->onTouchesEnded = [](const std::vector touches, Event* event){}; + + // Create new touchable nodes + for (int i = 0; i < this->_quantityOfNodes; ++i) + { + auto node = Node::create(); + node->setTag(1000 + i); + this->addChild(node); + this->_nodes.push_back(node); + dispatcher->addEventListenerWithSceneGraphPriority(listener->clone(), node); + } + + _lastRenderedCount = _quantityOfNodes; + } + + Size size = Director::getInstance()->getWinSize(); + EventTouch touchEvent; + touchEvent.setEventCode(EventTouch::EventCode::BEGAN); + std::vector touches; + + for (int i = 0; i < 4; ++i) + { + Touch* touch = new Touch(); + touch->autorelease(); + touch->setTouchInfo(i, rand() % 200, rand() % 200); + touches.push_back(touch); + } + touchEvent.setTouches(touches); + + CC_PROFILER_START(this->profilerName()); + dispatcher->dispatchEvent(&touchEvent); + CC_PROFILER_STOP(this->profilerName()); + } } , + + { "AllAtOnce-fixed", [=](){ + auto dispatcher = Director::getInstance()->getEventDispatcher(); + if (_quantityOfNodes != _lastRenderedCount) + { + auto listener = EventListenerTouchAllAtOnce::create(); + listener->onTouchesBegan = [](const std::vector touches, Event* event){}; + listener->onTouchesMoved = [](const std::vector touches, Event* event){}; + listener->onTouchesEnded = [](const std::vector touches, Event* event){}; + + for (int i = 0; i < this->_quantityOfNodes; ++i) + { + auto l = listener->clone(); + this->_fixedPriorityListeners.push_back(l); + dispatcher->addEventListenerWithFixedPriority(l, i+1); + } + + _lastRenderedCount = _quantityOfNodes; + } + + Size size = Director::getInstance()->getWinSize(); + EventTouch touchEvent; + touchEvent.setEventCode(EventTouch::EventCode::BEGAN); + std::vector touches; + + for (int i = 0; i < 4; ++i) + { + Touch* touch = new Touch(); + touch->autorelease(); + touch->setTouchInfo(i, rand() % 200, rand() % 200); + touches.push_back(touch); + } + touchEvent.setTouches(touches); + + CC_PROFILER_START(this->profilerName()); + dispatcher->dispatchEvent(&touchEvent); + CC_PROFILER_STOP(this->profilerName()); + } } , + + { "TouchModeMix-scenegraph", [=](){ + auto dispatcher = Director::getInstance()->getEventDispatcher(); + if (_quantityOfNodes != _lastRenderedCount) + { + auto listenerOneByOne = EventListenerTouchOneByOne::create(); + listenerOneByOne->onTouchBegan = [](Touch* touch, Event* event){ + return false; + }; + + listenerOneByOne->onTouchMoved = [](Touch* touch, Event* event){}; + listenerOneByOne->onTouchEnded = [](Touch* touch, Event* event){}; + + auto listenerAllAtOnce = EventListenerTouchAllAtOnce::create(); + listenerAllAtOnce->onTouchesBegan = [](const std::vector touches, Event* event){}; + listenerAllAtOnce->onTouchesMoved = [](const std::vector touches, Event* event){}; + listenerAllAtOnce->onTouchesEnded = [](const std::vector touches, Event* event){}; + + int i = 0; + // Create new touchable nodes + for (; i < this->_quantityOfNodes/2; ++i) + { + auto node = Node::create(); + node->setTag(1000 + i); + this->addChild(node); + this->_nodes.push_back(node); + dispatcher->addEventListenerWithSceneGraphPriority(listenerOneByOne->clone(), node); + } + + for (; i < this->_quantityOfNodes; ++i) + { + auto node = Node::create(); + node->setTag(1000 + i); + this->addChild(node); + this->_nodes.push_back(node); + dispatcher->addEventListenerWithSceneGraphPriority(listenerAllAtOnce->clone(), node); + } + + _lastRenderedCount = _quantityOfNodes; + } + + Size size = Director::getInstance()->getWinSize(); + EventTouch touchEvent; + touchEvent.setEventCode(EventTouch::EventCode::BEGAN); + std::vector touches; + + for (int i = 0; i < 4; ++i) + { + Touch* touch = new Touch(); + touch->autorelease(); + touch->setTouchInfo(i, rand() % 200, rand() % 200); + touches.push_back(touch); + } + touchEvent.setTouches(touches); + + CC_PROFILER_START(this->profilerName()); + dispatcher->dispatchEvent(&touchEvent); + CC_PROFILER_STOP(this->profilerName()); + } } , + + { "TouchModeMix-fixed", [=](){ + auto dispatcher = Director::getInstance()->getEventDispatcher(); + if (_quantityOfNodes != _lastRenderedCount) + { + auto listenerOneByOne = EventListenerTouchOneByOne::create(); + listenerOneByOne->onTouchBegan = [](Touch* touch, Event* event){ + return false; + }; + + listenerOneByOne->onTouchMoved = [](Touch* touch, Event* event){}; + listenerOneByOne->onTouchEnded = [](Touch* touch, Event* event){}; + + auto listenerAllAtOnce = EventListenerTouchAllAtOnce::create(); + listenerAllAtOnce->onTouchesBegan = [](const std::vector touches, Event* event){}; + listenerAllAtOnce->onTouchesMoved = [](const std::vector touches, Event* event){}; + listenerAllAtOnce->onTouchesEnded = [](const std::vector touches, Event* event){}; + + int i = 0; + + for (; i < this->_quantityOfNodes/2; ++i) + { + auto l = listenerOneByOne->clone(); + this->_fixedPriorityListeners.push_back(l); + dispatcher->addEventListenerWithFixedPriority(l, i+1); + } + + for (; i < this->_quantityOfNodes; ++i) + { + auto l = listenerAllAtOnce->clone(); + this->_fixedPriorityListeners.push_back(l); + dispatcher->addEventListenerWithFixedPriority(l, i+1); + } + + _lastRenderedCount = _quantityOfNodes; + } + + Size size = Director::getInstance()->getWinSize(); + EventTouch touchEvent; + touchEvent.setEventCode(EventTouch::EventCode::BEGAN); + std::vector touches; + + for (int i = 0; i < 4; ++i) + { + Touch* touch = new Touch(); + touch->autorelease(); + touch->setTouchInfo(i, rand() % 200, rand() % 200); + touches.push_back(touch); + } + touchEvent.setTouches(touches); + + CC_PROFILER_START(this->profilerName()); + dispatcher->dispatchEvent(&touchEvent); + CC_PROFILER_STOP(this->profilerName()); + } } , + }; + + for (const auto& func : testFunctions) + { + _testFunctions.push_back(func); + } +} + +std::string TouchEventDispatchingPerfTest::title() const +{ + return "Touch Event Dispatching Perf test"; +} + +std::string TouchEventDispatchingPerfTest::subtitle() const +{ + return "Test 'OneByOne-scenegraph', See console"; +} + +//////////////////////////////////////////////////////// +// +// KeyboardEventDispatchingPerfTest +// +//////////////////////////////////////////////////////// + +void KeyboardEventDispatchingPerfTest::generateTestFunctions() +{ + TestFunction testFunctions[] = { + { "keyboard-scenegraph", [=](){ + auto dispatcher = Director::getInstance()->getEventDispatcher(); + if (_quantityOfNodes != _lastRenderedCount) + { + auto listener = EventListenerKeyboard::create(); + listener->onKeyPressed = [](EventKeyboard::KeyCode keyCode, Event* event){}; + listener->onKeyReleased = [](EventKeyboard::KeyCode keyCode, Event* event){}; + + // Create new nodes listen to keyboard event + for (int i = 0; i < this->_quantityOfNodes; ++i) + { + auto node = Node::create(); + node->setTag(1000 + i); + this->addChild(node); + this->_nodes.push_back(node); + dispatcher->addEventListenerWithSceneGraphPriority(listener->clone(), node); + } + + _lastRenderedCount = _quantityOfNodes; + } + + EventKeyboard event(EventKeyboard::KeyCode::KEY_RETURN, true); + + CC_PROFILER_START(this->profilerName()); + dispatcher->dispatchEvent(&event); + CC_PROFILER_STOP(this->profilerName()); + } } , + + { "keyboard-fixed", [=](){ + auto dispatcher = Director::getInstance()->getEventDispatcher(); + if (_quantityOfNodes != _lastRenderedCount) + { + auto listener = EventListenerKeyboard::create(); + listener->onKeyPressed = [](EventKeyboard::KeyCode keyCode, Event* event){}; + listener->onKeyReleased = [](EventKeyboard::KeyCode keyCode, Event* event){}; + + for (int i = 0; i < this->_quantityOfNodes; ++i) + { + auto l = listener->clone(); + this->_fixedPriorityListeners.push_back(l); + dispatcher->addEventListenerWithFixedPriority(l, i+1); + } + + _lastRenderedCount = _quantityOfNodes; + } + + EventKeyboard event(EventKeyboard::KeyCode::KEY_RETURN, true); + + CC_PROFILER_START(this->profilerName()); + dispatcher->dispatchEvent(&event); + CC_PROFILER_STOP(this->profilerName()); + } } , + }; + + for (const auto& func : testFunctions) + { + _testFunctions.push_back(func); + } +} + +std::string KeyboardEventDispatchingPerfTest::title() const +{ + return "Keyboard Event Dispatching Perf test"; +} + +std::string KeyboardEventDispatchingPerfTest::subtitle() const +{ + return "Test 'keyboard-scenegraph', See console"; +} + +//////////////////////////////////////////////////////// +// +// CustomEventDispatchingPerfTest +// +//////////////////////////////////////////////////////// + +void CustomEventDispatchingPerfTest::onEnter() +{ + PerformanceEventDispatcherScene::onEnter(); + + for (int i = 0; i < 2000; i++) + { + auto listener = EventListenerCustom::create(StringUtils::format("custom_event_%d", i), [](EventCustom* event){}); + _eventDispatcher->addEventListenerWithFixedPriority(listener, i + 1); + _customListeners.push_back(listener); + } +} + +void CustomEventDispatchingPerfTest::onExit() +{ + for (auto& l : _customListeners) + { + _eventDispatcher->removeEventListener(l); + } + PerformanceEventDispatcherScene::onExit(); +} + +void CustomEventDispatchingPerfTest::generateTestFunctions() +{ + TestFunction testFunctions[] = { + { "custom-scenegraph", [=](){ + auto dispatcher = Director::getInstance()->getEventDispatcher(); + if (_quantityOfNodes != _lastRenderedCount) + { + auto listener = EventListenerCustom::create("custom_event_test_scenegraph", [](EventCustom* event){}); + + // Create new nodes listen to custom event + for (int i = 0; i < this->_quantityOfNodes; ++i) + { + auto node = Node::create(); + node->setTag(1000 + i); + this->addChild(node); + this->_nodes.push_back(node); + dispatcher->addEventListenerWithSceneGraphPriority(listener->clone(), node); + } + + _lastRenderedCount = _quantityOfNodes; + } + + EventCustom event("custom_event_test_scenegraph"); + + CC_PROFILER_START(this->profilerName()); + dispatcher->dispatchEvent(&event); + CC_PROFILER_STOP(this->profilerName()); + } } , + { "custom-fixed", [=](){ + auto dispatcher = Director::getInstance()->getEventDispatcher(); + if (_quantityOfNodes != _lastRenderedCount) + { + auto listener = EventListenerCustom::create("custom_event_test_fixed", [](EventCustom* event){}); + + for (int i = 0; i < this->_quantityOfNodes; ++i) + { + auto l = listener->clone(); + this->_fixedPriorityListeners.push_back(l); + dispatcher->addEventListenerWithFixedPriority(l, i+1); + } + + _lastRenderedCount = _quantityOfNodes; + } + + EventCustom event("custom_event_test_fixed"); + + CC_PROFILER_START(this->profilerName()); + dispatcher->dispatchEvent(&event); + CC_PROFILER_STOP(this->profilerName()); + } } , + }; + + for (const auto& func : testFunctions) + { + _testFunctions.push_back(func); + } +} + +std::string CustomEventDispatchingPerfTest::title() const +{ + return "Custom Event Dispatching Perf test"; +} + +std::string CustomEventDispatchingPerfTest::subtitle() const +{ + return "Test 'custom-scenegraph', See console"; +} + +///---------------------------------------- +void runEventDispatcherPerformanceTest() +{ + auto scene = createFunctions[g_curCase](); + scene->initWithQuantityOfNodes(kNodesIncrease); + + Director::getInstance()->replaceScene(scene); +} + diff --git a/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceEventDispatcher.h b/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceEventDispatcher.h new file mode 100644 index 0000000000..4b23966b44 --- /dev/null +++ b/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceEventDispatcher.h @@ -0,0 +1,106 @@ +// +// PerformanceEventDispatcher.h + +#ifndef __PERFORMANCE_EVENTDISPATCHER_TEST_H__ +#define __PERFORMANCE_EVENTDISPATCHER_TEST_H__ + +#include "PerformanceTest.h" +#include "CCProfiling.h" + +class EventDispatcherBasicLayer : public PerformBasicLayer +{ +public: + EventDispatcherBasicLayer(bool bControlMenuVisible, int nMaxCases = 0, int nCurCase = 0); + + virtual void showCurrentTest(); +}; + +class PerformanceEventDispatcherScene : public Scene +{ +public: + static const int TAG_TITLE = 100; + static const int TAG_SUBTITLE = 101; + + struct TestFunction + { + const char* name; + std::function func; + }; + + virtual void initWithQuantityOfNodes(unsigned int nNodes); + virtual void generateTestFunctions() = 0; + + virtual std::string title() const; + virtual std::string subtitle() const; + virtual void updateQuantityOfNodes(); + + const char* profilerName(); + void updateProfilerName(); + + // for the profiler + virtual const char* testName(); + void updateQuantityLabel(); + int getQuantityOfNodes() { return _quantityOfNodes; } + void dumpProfilerInfo(float dt); + + // overrides + virtual void update(float dt) override; + +protected: + char _profilerName[256]; + int _lastRenderedCount; + int _quantityOfNodes; + int _currentQuantityOfNodes; + unsigned int _type; + std::vector _testFunctions; + std::vector _nodes; + std::vector _fixedPriorityListeners; + MenuItemFont* _increase; + MenuItemFont* _decrease; + MenuItemFont* _startItem; + MenuItemFont* _stopItem; + MenuItemToggle* _toggle; +}; + +class TouchEventDispatchingPerfTest : public PerformanceEventDispatcherScene +{ +public: + CREATE_FUNC(TouchEventDispatchingPerfTest); + + virtual void generateTestFunctions() override; + + virtual std::string title() const override; + virtual std::string subtitle() const override; +}; + +class KeyboardEventDispatchingPerfTest : public PerformanceEventDispatcherScene +{ +public: + CREATE_FUNC(KeyboardEventDispatchingPerfTest); + + virtual void generateTestFunctions() override; + + virtual std::string title() const override; + virtual std::string subtitle() const override; +}; + +class CustomEventDispatchingPerfTest : public PerformanceEventDispatcherScene +{ +public: + CREATE_FUNC(CustomEventDispatchingPerfTest); + + virtual void onEnter() override; + virtual void onExit() override; + + virtual void generateTestFunctions() override; + + virtual std::string title() const override; + virtual std::string subtitle() const override; + +private: + std::vector _customListeners; +}; + +void runEventDispatcherPerformanceTest(); + +#endif /* defined(__PERFORMANCE_EVENTDISPATCHER_TEST_H__) */ diff --git a/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceTest.cpp b/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceTest.cpp index 7884aec8d3..b0c7554e30 100644 --- a/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceTest.cpp +++ b/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceTest.cpp @@ -9,6 +9,7 @@ #include "PerformanceLabelTest.h" #include "PerformanceRendererTest.h" #include "PerformanceContainerTest.h" +#include "PerformanceEventDispatcher.h" enum { @@ -29,7 +30,8 @@ struct { { "Touches Perf Test",[](Object*sender){runTouchesTest();} }, { "Label Perf Test",[](Object*sender){runLabelTest();} }, { "Renderer Perf Test",[](Object*sender){runRendererTest();} }, - { "Container Perf Test", [](Object* sender ) { runContainerPerformanceTest(); } } + { "Container Perf Test", [](Object* sender ) { runContainerPerformanceTest(); } }, + { "EventDispatcher Perf Test", [](Object* sender ) { runEventDispatcherPerformanceTest(); } }, }; static const int g_testMax = sizeof(g_testsName)/sizeof(g_testsName[0]); From 43a10f951b363da22a2bceef6af20ebab43d9e03 Mon Sep 17 00:00:00 2001 From: James Chen Date: Wed, 22 Jan 2014 13:35:52 +0800 Subject: [PATCH 2/5] issue #3677: Updates Android.mk and CMakeLists.txt. --- samples/Cpp/TestCpp/Android.mk | 1 + samples/Cpp/TestCpp/CMakeLists.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/samples/Cpp/TestCpp/Android.mk b/samples/Cpp/TestCpp/Android.mk index 080556535a..fa93be3210 100644 --- a/samples/Cpp/TestCpp/Android.mk +++ b/samples/Cpp/TestCpp/Android.mk @@ -123,6 +123,7 @@ Classes/PerformanceTest/PerformanceTouchesTest.cpp \ Classes/PerformanceTest/PerformanceLabelTest.cpp \ Classes/PerformanceTest/PerformanceRendererTest.cpp \ Classes/PerformanceTest/PerformanceContainerTest.cpp \ +Classes/PerformanceTest/PerformanceEventDispatcherTest.cpp \ Classes/PhysicsTest/PhysicsTest.cpp \ Classes/ReleasePoolTest/ReleasePoolTest.cpp \ Classes/RenderTextureTest/RenderTextureTest.cpp \ diff --git a/samples/Cpp/TestCpp/CMakeLists.txt b/samples/Cpp/TestCpp/CMakeLists.txt index 3251ff845f..bdc404e01f 100644 --- a/samples/Cpp/TestCpp/CMakeLists.txt +++ b/samples/Cpp/TestCpp/CMakeLists.txt @@ -118,6 +118,7 @@ set(SAMPLE_SRC Classes/PerformanceTest/PerformanceLabelTest.cpp Classes/PerformanceTest/PerformanceRendererTest.cpp Classes/PerformanceTest/PerformanceContainerTest.cpp + Classes/PerformanceTest/PerformanceEventDispatcherTest.cpp Classes/PhysicsTest/PhysicsTest.cpp Classes/ReleasePoolTest/ReleasePoolTest.cpp Classes/RenderTextureTest/RenderTextureTest.cpp From e3e248c0f0b046018cd04850bd1a25c1317125cb Mon Sep 17 00:00:00 2001 From: James Chen Date: Wed, 22 Jan 2014 13:53:54 +0800 Subject: [PATCH 3/5] issue #3677: Updates Windows project to add PerformanceEventDispatcherTest. --- samples/Cpp/TestCpp/proj.win32/TestCpp.vcxproj | 2 ++ samples/Cpp/TestCpp/proj.win32/TestCpp.vcxproj.filters | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/samples/Cpp/TestCpp/proj.win32/TestCpp.vcxproj b/samples/Cpp/TestCpp/proj.win32/TestCpp.vcxproj index 7b7132157b..41fb8bb922 100644 --- a/samples/Cpp/TestCpp/proj.win32/TestCpp.vcxproj +++ b/samples/Cpp/TestCpp/proj.win32/TestCpp.vcxproj @@ -187,6 +187,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\..\external\websockets\prebuilt\win32\*.*" "$ + @@ -336,6 +337,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\..\external\websockets\prebuilt\win32\*.*" "$ + diff --git a/samples/Cpp/TestCpp/proj.win32/TestCpp.vcxproj.filters b/samples/Cpp/TestCpp/proj.win32/TestCpp.vcxproj.filters index 95d347f44b..ede5992323 100644 --- a/samples/Cpp/TestCpp/proj.win32/TestCpp.vcxproj.filters +++ b/samples/Cpp/TestCpp/proj.win32/TestCpp.vcxproj.filters @@ -727,6 +727,9 @@ Classes\ReleasePoolTest + + Classes\PerformanceTest + @@ -1342,5 +1345,8 @@ Classes\ReleasePoolTest + + Classes\PerformanceTest + \ No newline at end of file From 32572e257eae7a57bb63395158ebcaff4729f382 Mon Sep 17 00:00:00 2001 From: James Chen Date: Wed, 22 Jan 2014 14:10:42 +0800 Subject: [PATCH 4/5] issue #3677: File rename. PerformanceEventDispatcher.h/.cpp -> PerformanceEventDispatcherTest.h/.cpp. --- .../cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id | 2 +- ...EventDispatcher.cpp => PerformanceEventDispatcherTest.cpp} | 4 ++-- ...anceEventDispatcher.h => PerformanceEventDispatcherTest.h} | 2 +- samples/Cpp/TestCpp/proj.win32/TestCpp.vcxproj | 4 ++-- samples/Cpp/TestCpp/proj.win32/TestCpp.vcxproj.filters | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) rename samples/Cpp/TestCpp/Classes/PerformanceTest/{PerformanceEventDispatcher.cpp => PerformanceEventDispatcherTest.cpp} (99%) rename samples/Cpp/TestCpp/Classes/PerformanceTest/{PerformanceEventDispatcher.h => PerformanceEventDispatcherTest.h} (98%) diff --git a/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id index 118f1ee7eb..dc3bae7a56 100644 --- a/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -4f83e9cf42efe5a2a604cf4381c3acd757f0c3ce \ No newline at end of file +ff284ac388641341140f8b6817f2cd26e4f07cf2 \ No newline at end of file diff --git a/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceEventDispatcher.cpp b/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceEventDispatcherTest.cpp similarity index 99% rename from samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceEventDispatcher.cpp rename to samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceEventDispatcherTest.cpp index f0737e6df5..28953d22ff 100644 --- a/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceEventDispatcher.cpp +++ b/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceEventDispatcherTest.cpp @@ -1,8 +1,8 @@ // -// PerformanceEventDispatcher.cpp +// PerformanceEventDispatcherTest.cpp // -#include "PerformanceEventDispatcher.h" +#include "PerformanceEventDispatcherTest.h" #include diff --git a/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceEventDispatcher.h b/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceEventDispatcherTest.h similarity index 98% rename from samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceEventDispatcher.h rename to samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceEventDispatcherTest.h index 4b23966b44..b8b6022b62 100644 --- a/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceEventDispatcher.h +++ b/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceEventDispatcherTest.h @@ -1,5 +1,5 @@ // -// PerformanceEventDispatcher.h +// PerformanceEventDispatcherTest.h #ifndef __PERFORMANCE_EVENTDISPATCHER_TEST_H__ #define __PERFORMANCE_EVENTDISPATCHER_TEST_H__ diff --git a/samples/Cpp/TestCpp/proj.win32/TestCpp.vcxproj b/samples/Cpp/TestCpp/proj.win32/TestCpp.vcxproj index 41fb8bb922..620b12b3f1 100644 --- a/samples/Cpp/TestCpp/proj.win32/TestCpp.vcxproj +++ b/samples/Cpp/TestCpp/proj.win32/TestCpp.vcxproj @@ -187,7 +187,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\..\external\websockets\prebuilt\win32\*.*" "$ - + @@ -337,7 +337,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\..\external\websockets\prebuilt\win32\*.*" "$ - + diff --git a/samples/Cpp/TestCpp/proj.win32/TestCpp.vcxproj.filters b/samples/Cpp/TestCpp/proj.win32/TestCpp.vcxproj.filters index ede5992323..2600ec0428 100644 --- a/samples/Cpp/TestCpp/proj.win32/TestCpp.vcxproj.filters +++ b/samples/Cpp/TestCpp/proj.win32/TestCpp.vcxproj.filters @@ -727,7 +727,7 @@ Classes\ReleasePoolTest - + Classes\PerformanceTest @@ -1345,7 +1345,7 @@ Classes\ReleasePoolTest - + Classes\PerformanceTest From 444a30e22627dc9c4ac7a050092cd2710f13e990 Mon Sep 17 00:00:00 2001 From: James Chen Date: Wed, 22 Jan 2014 14:12:25 +0800 Subject: [PATCH 5/5] issue #3677: Wrong include fix. --- samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceTest.cpp b/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceTest.cpp index b0c7554e30..63ce78dfe3 100644 --- a/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceTest.cpp +++ b/samples/Cpp/TestCpp/Classes/PerformanceTest/PerformanceTest.cpp @@ -9,7 +9,7 @@ #include "PerformanceLabelTest.h" #include "PerformanceRendererTest.h" #include "PerformanceContainerTest.h" -#include "PerformanceEventDispatcher.h" +#include "PerformanceEventDispatcherTest.h" enum {