void NodeChildrenMainScene::dumpProfilerInfo(float dt)
{
    CC_PROFILER_DISPLAY_TIMERS();
    
    if (this->isAutoTesting()) {
        // record the test result to class Profile
        auto timer = Profiler::getInstance()->_activeTimers.at(_profilerName);
        auto numStr = genStr("%d", quantityOfNodes);
        auto avgStr = genStr("%ldµ", timer->_averageTime2);
        auto minStr = genStr("%ldµ", timer->minTime);
        auto maxStr = genStr("%ldµ", timer->maxTime);
        Profile::getInstance()->addTestResult(genStrVector(getTestCaseName().c_str(), numStr.c_str(), nullptr),
                                              genStrVector(avgStr.c_str(), minStr.c_str(), maxStr.c_str(), nullptr));
        
        auto testsSize = sizeof(autoTestNodesNums)/sizeof(int);
        if (autoTestIndex >= (testsSize - 1)) {
            // if it's the last one of auto test. End the auto test.
            this->setAutoTesting(false);
            Profile::getInstance()->testCaseEnd();
        }
        else
        {
            // update the auto test index
            autoTestIndex++;
            quantityOfNodes = autoTestNodesNums[autoTestIndex];
            updateQuantityLabel();
            updateQuantityOfNodes();
            updateProfilerName();
            CC_PROFILER_PURGE_ALL();
        }
    }
}
void PerformanceEventDispatcherScene::dumpProfilerInfo(float dt)
{
	CC_PROFILER_DISPLAY_TIMERS();
}
void NodeChildrenMenuLayer::dumpProfilerInfo(float dt)
{
	CC_PROFILER_DISPLAY_TIMERS();
}
void TouchesPerformTest3::onEnter()
{
    PerformBasicLayer::onEnter();
    
    
    auto s = Director::getInstance()->getWinSize();
    
    // add title
    auto label = Label::createWithTTF(title().c_str(), "fonts/arial.ttf", 32);
    addChild(label, 1);
    label->setPosition(Vec2(s.width/2, s.height-50));
    
#define TOUCH_PROFILER_NAME  "TouchProfileName"
#define TOUCHABLE_NODE_NUM 1000
    
    srand((unsigned)time(nullptr));
    
    for (int i = 0; i < TOUCHABLE_NODE_NUM; ++i)
    {
        int zorder = rand() % TOUCHABLE_NODE_NUM;
        auto layer = new (std::nothrow) TouchableLayer();
        
        auto listener = EventListenerTouchOneByOne::create();
        listener->onTouchBegan = CC_CALLBACK_2(TouchableLayer::onTouchBegan, layer);
        listener->onTouchMoved = CC_CALLBACK_2(TouchableLayer::onTouchMoved, layer);
        listener->onTouchEnded = CC_CALLBACK_2(TouchableLayer::onTouchEnded, layer);
        listener->onTouchCancelled = CC_CALLBACK_2(TouchableLayer::onTouchCancelled, layer);
        _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, layer);
        
        addChild(layer, zorder);
        layer->release();
    }
    
    auto emitEventlabel = Label::createWithSystemFont("Emit Touch Event", "", 24);
    auto menuItem = MenuItemLabel::create(emitEventlabel, [this](Ref* sender){
        
        CC_PROFILER_PURGE_ALL();
        
        std::vector<Touch*> touches;
        for (int i = 0; i < EventTouch::MAX_TOUCHES; ++i)
        {
            Touch* touch = new (std::nothrow) Touch();
            touch->setTouchInfo(i, 10, (i+1) * 10);
            touches.push_back(touch);
        }
        
        EventTouch event;
        event.setEventCode(EventTouch::EventCode::BEGAN);
        event.setTouches(touches);
        
        for (int i = 0; i < 100; ++i)
        {
            CC_PROFILER_START(TOUCH_PROFILER_NAME);
            
            _eventDispatcher->dispatchEvent(&event);
            
            CC_PROFILER_STOP(TOUCH_PROFILER_NAME);
        }
        
        CC_PROFILER_DISPLAY_TIMERS();
        
        for (auto& touch : touches)
        {
            touch->release();
        }
    });
    
    menuItem->setPosition(Vec2(0, -20));
    auto menu = Menu::create(menuItem, nullptr);
    addChild(menu);
}
void PerformanceContainerScene::dumpProfilerInfo(float dt)
{
	CC_PROFILER_DISPLAY_TIMERS();
}
void PerformanceCallbackScene::dumpProfilerInfo(float dt)
{
	CC_PROFILER_DISPLAY_TIMERS();
}
void TouchesPerformTest3::onEnter()
{
    PerformBasicLayer::onEnter();
    
    
    auto s = Director::getInstance()->getWinSize();
    
    // add title
    auto label = LabelTTF::create(title().c_str(), "Arial", 32);
    addChild(label, 1);
    label->setPosition(Point(s.width/2, s.height-50));
    
#define TOUCH_PROFILER_NAME  "TouchProfileName"
#define TOUCHABLE_NODE_NUM 1000
    
    srand(time(nullptr));
    
    for (int i = 0; i < TOUCHABLE_NODE_NUM; ++i)
    {
        int zorder = rand() % TOUCHABLE_NODE_NUM;
        auto layer = new TouchableLayer();
        layer->setTouchEnabled(true);
        layer->setTouchMode(Touch::DispatchMode::ONE_BY_ONE);
        addChild(layer, zorder);
        layer->release();
    }
    
    auto emitEventlabel = LabelTTF::create("Emit Touch Event", "", 24);
    auto menuItem = MenuItemLabel::create(emitEventlabel, [](Object* sender){
        
        CC_PROFILER_PURGE_ALL();
        
        std::vector<Touch*> touches;
        for (int i = 0; i < EventTouch::MAX_TOUCHES; ++i)
        {
            Touch* touch = new Touch();
            touch->setTouchInfo(i, 10, (i+1) * 10);
            touches.push_back(touch);
        }
        
        EventTouch event;
        event.setEventCode(EventTouch::EventCode::BEGAN);
        event.setTouches(touches);
        
        auto dispatcher = EventDispatcher::getInstance();
        
        for (int i = 0; i < 100; ++i)
        {
            CC_PROFILER_START(TOUCH_PROFILER_NAME);
            
            dispatcher->dispatchEvent(&event, false);
            
            CC_PROFILER_STOP(TOUCH_PROFILER_NAME);
        }
        
        CC_PROFILER_DISPLAY_TIMERS();
        
        for (auto& touch : touches)
        {
            touch->release();
        }
    });
    
    menuItem->setPosition(Point(0, -20));
    auto menu = Menu::create(menuItem, NULL);
    addChild(menu);
}
void PerformceAllocScene::dumpProfilerInfo(float dt)
{
	CC_PROFILER_DISPLAY_TIMERS();
}