Merge branch 'devel/master' into tizen
[platform/core/uifw/dali-demo.git] / examples / logging / logging-example.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include "shared/view.h"
19 #include <dali/dali.h>
20 #include <dali-toolkit/dali-toolkit.h>
21 #include <dali/devel-api/adaptor-framework/performance-logger.h>
22 #include <sstream>
23
24 using namespace Dali;
25
26 // Define this so that it is interchangeable
27 // "DP" stands for Device independent Pixels
28 #define DP(x) x
29
30 //enum ButtonType
31 //{
32 //  PUSH_BUTTON,
33 //  TOGGLE_BUTTON
34 //};
35 //
36 //struct ButtonItem
37 //{
38 //  ButtonType type;
39 //  const char* name;
40 //  const char* text;
41 //  const char* altText;
42 //};
43
44 namespace
45 {
46
47 const char* const BACKGROUND_IMAGE = DEMO_IMAGE_DIR "background-gradient.jpg";
48 const char* const TOOLBAR_IMAGE = DEMO_IMAGE_DIR "top-bar.png";
49
50 const char* const TOOLBAR_TITLE = "Logging";
51 //const int TOOLBAR_HEIGHT = 62;
52
53 const int MARGIN_SIZE = 10;
54 const int TOP_MARGIN = 85;
55
56 const int LOGGER_GROUP_HEIGHT = 84;
57 const int LOGGER_RADIO_GROUP_HEIGHT = 200;
58
59 const int LOGGER_RADIO_SPACING = 48;
60
61 const int CONSOLE_HEIGHT = 84;
62
63 const int BUTTON_WIDTH = 200;
64 const int BUTTON_HEIGHT = LOGGER_GROUP_HEIGHT - MARGIN_SIZE * 2;
65
66 const Vector4 BACKGROUND_COLOUR( 1.0f, 1.0f, 1.0f, 0.15f );
67
68 // Button IDs
69 const char* const LOGGER_1_RADIO_ID = "LOGGER_1_RADIO";
70 const char* const LOGGER_2_RADIO_ID = "LOGGER_2_RADIO";
71 const char* const LOGGER_3_RADIO_ID = "LOGGER_3_RADIO";
72
73 const char* const FREQUENCY_1_RADIO_ID = "FREQUENCY_1_RADIO";
74 const char* const FREQUENCY_2_RADIO_ID = "FREQUENCY_2_RADIO";
75 const char* const FREQUENCY_3_RADIO_ID = "FREQUENCY_3_RADIO";
76
77 const char* const CREATE_BUTTON_ID = "CREATE_BUTTON";
78 const char* const DELETE_BUTTON_ID = "DELETE_BUTTON";
79 const char* const START_BUTTON_ID = "START_BUTTON";
80 const char* const STOP_BUTTON_ID = "STOP_BUTTON";
81 const char* const HIGH_FREQ_BUTTON_ID = "INC_FREQ_BUTTON";
82 const char* const LOW_FREQ_BUTTON_ID = "DEC_FREQ_BUTTON";
83 const char* const ENABLE_BUTTON_ID = "ENABLE_BUTTON";
84 const char* const DISABLE_BUTTON_ID = "DISABLE_BUTTON";
85 const char* const VSYNC_BUTTON_ID = "VSYNC_BUTTON";
86
87 const char* const CREATE_BUTTON_TEXT = "Create";
88 const char* const DELETE_BUTTON_TEXT = "Delete";
89 const char* const START_BUTTON_TEXT = "Start";
90 const char* const STOP_BUTTON_TEXT = "Stop";
91 const char* const ENABLE_BUTTON_TEXT = "Enable";
92 const char* const DISABLE_BUTTON_TEXT = "Disable";
93 const char* const VSYNC_BUTTON_TEXT = "Vsync";
94
95 const char* const FREQUENCY_1_RADIO_TEXT = "1";
96 const char* const FREQUENCY_2_RADIO_TEXT = "2";
97 const char* const FREQUENCY_3_RADIO_TEXT = "10";
98
99 const char* const LOGGER_TEXT = "Logger:";
100 const char* const FREQUENCY_TEXT = "Frequency (sec):";
101
102 const unsigned int NUM_LOGGERS = 3;
103
104 const unsigned int HIGH_FREQUENCY = 1;   // Seconds
105 const unsigned int MEDIUM_FREQUENCY = 2;   // Seconds
106 const unsigned int LOW_FREQUENCY = 10;   // Seconds
107 const unsigned int NUM_FREQUENCIES = 3;
108
109 }  // namespace
110
111 /**
112  * This example is a test harness for performance loggers.
113  *
114  * Press one of the create buttons to create a logger. This will output on vsync at the default frequency (2 seconds).
115  * In case nothing appears in the log, force a vsync by touching anywhere on the screen. Loggers can be deleted
116  * with the delete buttons. They can be enabled or disabled in which case logging will appear or disappear in the console
117  * respectively. To record information in a logger press the start and then stop button in succession quickly in between
118  * the time period when it would print to the console. This is necessary as the logger is cleared of information when
119  * it prints. The output will contain the smallest and largest times between start and stop recorded (minimum and maximum),
120  * the total time recorded by the logger as well as the average and standard deviation of all the times recorded. The
121  * frequency of log output can be set to high frequency (every 1 second) or low frequency (every 10 seconds).
122  */
123 class LoggingController: public ConnectionTracker
124 {
125  public:
126
127   LoggingController( Application& application )
128     : mApplication( application )
129   {
130     // Connect to the Application's Init signal
131     mApplication.InitSignal().Connect( this, &LoggingController::Create );
132   }
133
134   ~LoggingController()
135   {
136     // Nothing to do here
137   }
138
139   void Create( Application& application )
140   {
141     // The Init signal is received once (only) during the Application lifetime
142
143     mCurrentLogger = 0;
144     mPerformanceLoggers.reserve( NUM_LOGGERS );
145     mPerformanceLoggers.resize( NUM_LOGGERS );
146
147     mPerformanceLoggerNames.reserve( NUM_LOGGERS );
148     mPerformanceLoggerNames.resize( NUM_LOGGERS );
149
150     mLoggerStates.reserve( NUM_LOGGERS );
151     mLoggerStates.resize( NUM_LOGGERS );
152
153     mLogRadioButtons.reserve( NUM_LOGGERS );
154     mLogRadioButtons.resize( NUM_LOGGERS );
155
156     mFrequencyRadioButtons.reserve( NUM_FREQUENCIES );
157     mFrequencyRadioButtons.resize( NUM_FREQUENCIES );
158
159     // Respond to key events
160     Stage::GetCurrent().KeyEventSignal().Connect(this, &LoggingController::OnKeyEvent);
161
162     // Creates a default view with a default tool bar.
163     // The view is added to the stage.
164     mContentLayer = DemoHelper::CreateView( application,
165                                             mView,
166                                             mToolBar,
167                                             BACKGROUND_IMAGE,
168                                             TOOLBAR_IMAGE,
169                                             TOOLBAR_TITLE );
170
171     Toolkit::TableView contentTable = Toolkit::TableView::New( 6, 1 );
172     contentTable.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
173     contentTable.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
174     contentTable.SetAnchorPoint( AnchorPoint::TOP_LEFT );
175     contentTable.SetParentOrigin( ParentOrigin::TOP_LEFT );
176     contentTable.SetCellPadding( Size( MARGIN_SIZE, MARGIN_SIZE * 0.5f ) );
177 //    contentTable.TouchedSignal().Connect( this, &LoggingController::OnTouchEvent );
178
179     for( unsigned int i = 0; i < contentTable.GetRows(); ++i )
180     {
181       contentTable.SetFitHeight( i );
182     }
183
184     contentTable.SetPosition( 0.0f, TOP_MARGIN );
185
186     mContentLayer.Add( contentTable );
187
188
189     // Logger selector radio group
190     Toolkit::TableView radioGroupBackground = Toolkit::TableView::New( 2, 1 );
191     radioGroupBackground.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
192     radioGroupBackground.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
193     radioGroupBackground.SetBackgroundColor( BACKGROUND_COLOUR );
194     radioGroupBackground.SetParentOrigin( ParentOrigin::TOP_LEFT );
195     radioGroupBackground.SetAnchorPoint( AnchorPoint::TOP_LEFT );
196     radioGroupBackground.SetCellPadding( Size( MARGIN_SIZE, MARGIN_SIZE * 0.5f ) );
197
198     contentTable.Add( radioGroupBackground );
199
200     // Label
201     {
202       Toolkit::TextLabel label = Toolkit::TextLabel::New( LOGGER_TEXT );
203       label.SetParentOrigin( ParentOrigin::TOP_LEFT );
204       label.SetAnchorPoint( AnchorPoint::TOP_LEFT );
205       label.SetPosition( DP(MARGIN_SIZE), DP(MARGIN_SIZE) );
206       label.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
207
208       radioGroupBackground.Add( label );
209       radioGroupBackground.SetFitHeight( 0 );
210     }
211
212     // Radio group
213     Toolkit::TableView radioButtonsGroup = Toolkit::TableView::New( 3, 1 );
214     radioButtonsGroup.SetCellPadding( Size( 0.0f, MARGIN_SIZE * 0.5f ) );
215     radioButtonsGroup.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
216     for( unsigned int i = 0; i < radioButtonsGroup.GetRows(); ++i )
217     {
218       radioButtonsGroup.SetFitHeight( i );
219     }
220     radioButtonsGroup.SetFitWidth( 0 );
221
222     radioGroupBackground.Add( radioButtonsGroup );
223     radioGroupBackground.SetFitHeight( 1 );
224
225     int radioX = 0;
226     int radioY = 0;
227
228     // Radio 1
229     {
230       Toolkit::RadioButton radioButton = Toolkit::RadioButton::New();
231       radioButton.SetName( LOGGER_1_RADIO_ID );
232       radioButton.SetParentOrigin( ParentOrigin::TOP_LEFT );
233       radioButton.SetAnchorPoint( AnchorPoint::TOP_LEFT );
234       radioButton.SetPosition( DP(radioX), DP(radioY) );
235       radioButton.SetSelected( true );
236
237       radioButton.StateChangedSignal().Connect( this, &LoggingController::LoggingRadioSelect );
238
239       radioButtonsGroup.Add( radioButton );
240       mLogRadioButtons[0] = radioButton;
241     }
242
243     // Radio 2
244     {
245       radioY += LOGGER_RADIO_SPACING;
246
247       Toolkit::RadioButton radioButton = Toolkit::RadioButton::New();
248       radioButton.SetName( LOGGER_2_RADIO_ID );
249       radioButton.SetParentOrigin( ParentOrigin::TOP_LEFT );
250       radioButton.SetAnchorPoint( AnchorPoint::TOP_LEFT );
251       radioButton.SetPosition( DP(radioX), DP(radioY) );
252
253       radioButton.StateChangedSignal().Connect( this, &LoggingController::LoggingRadioSelect );
254
255       radioButtonsGroup.Add( radioButton );
256       mLogRadioButtons[1] = radioButton;
257     }
258
259     // Radio 3
260     {
261       radioY += LOGGER_RADIO_SPACING;
262
263       Toolkit::RadioButton radioButton = Toolkit::RadioButton::New();
264       radioButton.SetName( LOGGER_3_RADIO_ID );
265       radioButton.SetParentOrigin( ParentOrigin::TOP_LEFT );
266       radioButton.SetAnchorPoint( AnchorPoint::TOP_LEFT );
267       radioButton.SetPosition( DP(radioX), DP(radioY) );
268
269       radioButton.StateChangedSignal().Connect( this, &LoggingController::LoggingRadioSelect );
270
271       radioButtonsGroup.Add( radioButton );
272       mLogRadioButtons[2] = radioButton;
273     }
274
275     // Create/delete/disable group
276     Toolkit::TableView createGroupBackground = Toolkit::TableView::New( 1, 2 );
277     createGroupBackground.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
278     createGroupBackground.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
279     createGroupBackground.SetBackgroundColor( BACKGROUND_COLOUR );
280     createGroupBackground.SetCellPadding( Size( MARGIN_SIZE, MARGIN_SIZE ) );
281     createGroupBackground.SetFitHeight( 0 );
282
283     contentTable.Add( createGroupBackground );
284
285     {
286       Toolkit::PushButton button = Toolkit::PushButton::New();
287       button.SetName( CREATE_BUTTON_ID );
288       button.SetLabelText( CREATE_BUTTON_TEXT );
289       button.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
290       button.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
291       button.ClickedSignal().Connect( this, &LoggingController::OnButtonClicked );
292
293       createGroupBackground.Add( button );
294     }
295
296     {
297       Toolkit::PushButton button = Toolkit::PushButton::New();
298       button.SetName( DELETE_BUTTON_ID );
299       button.SetLabelText( DELETE_BUTTON_TEXT );
300       button.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
301       button.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
302       button.ClickedSignal().Connect( this, &LoggingController::OnButtonClicked );
303
304       createGroupBackground.Add( button );
305     }
306
307     // Start/stop group
308
309     Toolkit::TableView timingGroupBackground = Toolkit::TableView::New( 1, 2 );
310     timingGroupBackground.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
311     timingGroupBackground.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
312     timingGroupBackground.SetBackgroundColor( BACKGROUND_COLOUR );
313     timingGroupBackground.SetCellPadding( Size( MARGIN_SIZE, MARGIN_SIZE ) );
314     timingGroupBackground.SetFitHeight( 0 );
315
316     contentTable.Add( timingGroupBackground );
317
318     {
319       Toolkit::PushButton button = Toolkit::PushButton::New();
320       button.SetName( START_BUTTON_ID );
321       button.SetLabelText( START_BUTTON_TEXT );
322       button.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
323       button.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
324       button.ClickedSignal().Connect( this, &LoggingController::OnButtonClicked );
325
326       timingGroupBackground.Add( button );
327     }
328
329     {
330       Toolkit::PushButton button = Toolkit::PushButton::New();
331       button.SetName( STOP_BUTTON_ID );
332       button.SetLabelText( STOP_BUTTON_TEXT );
333       button.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
334       button.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
335       button.ClickedSignal().Connect( this, &LoggingController::OnButtonClicked );
336
337       timingGroupBackground.Add( button );
338     }
339
340     // Enable/disable group
341     Toolkit::TableView enableGroupBackground = Toolkit::TableView::New( 1, 2 );
342     enableGroupBackground.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
343     enableGroupBackground.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
344     enableGroupBackground.SetBackgroundColor( BACKGROUND_COLOUR );
345     enableGroupBackground.SetCellPadding( Size( MARGIN_SIZE, MARGIN_SIZE ) );
346     enableGroupBackground.SetFitHeight( 0 );
347
348     contentTable.Add( enableGroupBackground );
349
350     {
351       Toolkit::PushButton button = Toolkit::PushButton::New();
352       button.SetName( ENABLE_BUTTON_ID );
353       button.SetLabelText( ENABLE_BUTTON_TEXT );
354       button.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
355       button.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
356       button.ClickedSignal().Connect( this, &LoggingController::OnButtonClicked );
357
358       enableGroupBackground.Add( button );
359     }
360
361     {
362       Toolkit::PushButton button = Toolkit::PushButton::New();
363       button.SetName( DISABLE_BUTTON_ID );
364       button.SetLabelText( DISABLE_BUTTON_TEXT );
365       button.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
366       button.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
367       button.ClickedSignal().Connect( this, &LoggingController::OnButtonClicked );
368
369       enableGroupBackground.Add( button );
370     }
371
372     // Logger selector radio group
373     Toolkit::TableView frequencyRadioGroupBackground = Toolkit::TableView::New( 2, 1 );
374     frequencyRadioGroupBackground.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
375     frequencyRadioGroupBackground.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
376     frequencyRadioGroupBackground.SetBackgroundColor( BACKGROUND_COLOUR );
377     frequencyRadioGroupBackground.SetCellPadding( Size( MARGIN_SIZE, MARGIN_SIZE * 0.5f ) );
378     frequencyRadioGroupBackground.SetFitHeight( 0 );
379     frequencyRadioGroupBackground.SetFitHeight( 1 );
380
381     contentTable.Add( frequencyRadioGroupBackground );
382
383     // Label
384     {
385       Toolkit::TextLabel label = Toolkit::TextLabel::New( FREQUENCY_TEXT );
386
387       frequencyRadioGroupBackground.Add( label );
388     }
389
390     // Radio group
391     Toolkit::TableView frequencyRadioButtonsGroup = Toolkit::TableView::New( 1, 3 );
392     frequencyRadioButtonsGroup.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
393     frequencyRadioButtonsGroup.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
394     frequencyRadioButtonsGroup.SetFitHeight( 0 );
395     frequencyRadioButtonsGroup.SetPadding( Padding( 0.0f, 0.0f, MARGIN_SIZE, 0.0f ) );
396
397     frequencyRadioGroupBackground.Add( frequencyRadioButtonsGroup );
398
399     // Radio 1
400     {
401       Toolkit::RadioButton radioButton = Toolkit::RadioButton::New( FREQUENCY_1_RADIO_TEXT );
402       radioButton.SetName( FREQUENCY_1_RADIO_ID );
403
404       radioButton.StateChangedSignal().Connect( this, &LoggingController::FrequencyRadioSelect );
405
406       frequencyRadioButtonsGroup.Add( radioButton );
407       mFrequencyRadioButtons[0] = radioButton;
408     }
409
410     // Radio 2
411     {
412       Toolkit::RadioButton radioButton = Toolkit::RadioButton::New( FREQUENCY_2_RADIO_TEXT );
413       radioButton.SetName( FREQUENCY_2_RADIO_ID );
414
415       radioButton.SetSelected( true );
416
417       radioButton.StateChangedSignal().Connect( this, &LoggingController::FrequencyRadioSelect );
418
419       frequencyRadioButtonsGroup.Add( radioButton );
420       mFrequencyRadioButtons[1] = radioButton;
421     }
422
423     // Radio 3
424     {
425       Toolkit::RadioButton radioButton = Toolkit::RadioButton::New( FREQUENCY_3_RADIO_TEXT );
426       radioButton.SetName( FREQUENCY_3_RADIO_ID );
427
428       radioButton.StateChangedSignal().Connect( this, &LoggingController::FrequencyRadioSelect );
429
430       frequencyRadioButtonsGroup.Add( radioButton );
431       mFrequencyRadioButtons[2] = radioButton;
432     }
433
434     // Vsync group
435     Toolkit::TableView vsyncGroupBackground = Toolkit::TableView::New( 1, 1 );
436     vsyncGroupBackground.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
437     vsyncGroupBackground.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
438     vsyncGroupBackground.SetBackgroundColor( BACKGROUND_COLOUR );
439     vsyncGroupBackground.SetCellPadding( Size( MARGIN_SIZE, MARGIN_SIZE ) );
440     vsyncGroupBackground.SetFitHeight( 0 );
441
442     contentTable.Add( vsyncGroupBackground );
443
444     {
445       Toolkit::PushButton button = Toolkit::PushButton::New();
446       button.SetName( VSYNC_BUTTON_ID );
447       button.SetLabelText( VSYNC_BUTTON_TEXT );
448       button.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
449       button.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
450       button.ClickedSignal().Connect( this, &LoggingController::OnButtonClicked );
451
452       vsyncGroupBackground.Add( button );
453     }
454
455     WriteConsole();
456   }
457
458   void WriteConsole()
459   {
460     for( unsigned int i = 0; i < NUM_LOGGERS; ++i)
461     {
462       std::stringstream ss;
463       ss << (i + 1) << ") " << ((mPerformanceLoggers[i]) ? "Created" : "Deleted")
464          << ", " << ((mLoggerStates[i].isTiming) ? "Started" : "Stopped")
465          << ", " << ((mLoggerStates[i].isEnabled) ? "Enabled" : "Disabled");
466
467       mLogRadioButtons[i].SetLabelText( ss.str() );
468     }
469   }
470
471   bool LoggingRadioSelect( Toolkit::Button button )
472   {
473     if( button.GetName() == LOGGER_1_RADIO_ID && button.IsSelected() == true )
474     {
475       mCurrentLogger = 0;
476     }
477     else if( button.GetName() == LOGGER_2_RADIO_ID && button.IsSelected() == true )
478     {
479       mCurrentLogger = 1;
480     }
481     else if( button.GetName() == LOGGER_3_RADIO_ID && button.IsSelected() == true )
482     {
483       mCurrentLogger = 2;
484     }
485
486     UpdateState();
487
488     return true;
489   }
490
491   void UpdateState()
492   {
493     DALI_ASSERT_DEBUG( mCurrentLogger < mLoggerStates.size() );
494     const unsigned int frequency = mLoggerStates[mCurrentLogger].frequency;
495     if( frequency == HIGH_FREQUENCY )
496     {
497       mFrequencyRadioButtons[0].SetSelected( true );
498     }
499     else if( frequency == MEDIUM_FREQUENCY )
500     {
501       mFrequencyRadioButtons[1].SetSelected( true );
502     }
503     else if( frequency == LOW_FREQUENCY )
504     {
505       mFrequencyRadioButtons[2].SetSelected( true );
506     }
507   }
508
509   bool FrequencyRadioSelect( Toolkit::Button button )
510   {
511     if( button.GetName() == FREQUENCY_1_RADIO_ID && button.IsSelected() == true )
512     {
513       if( mPerformanceLoggers[mCurrentLogger] )
514       {
515         DALI_ASSERT_DEBUG( mCurrentLogger < mPerformanceLoggers.size() );
516         mPerformanceLoggers[mCurrentLogger].SetLoggingFrequency( HIGH_FREQUENCY );
517
518         DALI_ASSERT_DEBUG( mCurrentLogger < mLoggerStates.size() );
519         mLoggerStates[mCurrentLogger].frequency = HIGH_FREQUENCY;
520       }
521     }
522     else if( button.GetName() == FREQUENCY_2_RADIO_ID && button.IsSelected() == true )
523     {
524       if( mPerformanceLoggers[mCurrentLogger] )
525       {
526         DALI_ASSERT_DEBUG( mCurrentLogger < mPerformanceLoggers.size() );
527         mPerformanceLoggers[mCurrentLogger].SetLoggingFrequency( MEDIUM_FREQUENCY );
528
529         DALI_ASSERT_DEBUG( mCurrentLogger < mLoggerStates.size() );
530         mLoggerStates[mCurrentLogger].frequency = MEDIUM_FREQUENCY;
531       }
532     }
533     else if( button.GetName() == FREQUENCY_3_RADIO_ID && button.IsSelected() == true )
534     {
535       if( mPerformanceLoggers[mCurrentLogger] )
536       {
537         DALI_ASSERT_DEBUG( mCurrentLogger < mPerformanceLoggers.size() );
538         mPerformanceLoggers[mCurrentLogger].SetLoggingFrequency( LOW_FREQUENCY );
539
540         DALI_ASSERT_DEBUG( mCurrentLogger < mLoggerStates.size() );
541         mLoggerStates[mCurrentLogger].frequency = LOW_FREQUENCY;
542       }
543     }
544
545     return true;
546   }
547
548   void OnKeyEvent( const KeyEvent& event )
549   {
550     if( event.state == KeyEvent::Down )
551     {
552       if( IsKey( event, Dali::DALI_KEY_ESCAPE ) || IsKey( event, Dali::DALI_KEY_BACK ) )
553       {
554         // Exit application when click back or escape.
555         mApplication.Quit();
556       }
557     }
558   }
559
560   bool OnButtonClicked(Toolkit::Button button)
561   {
562     if( button.GetName() == CREATE_BUTTON_ID )
563     {
564       std::stringstream ss;
565       ss << "Test logger " << (mCurrentLogger + 1);
566
567       DALI_ASSERT_DEBUG( mCurrentLogger < mPerformanceLoggerNames.size() );
568       mPerformanceLoggerNames[mCurrentLogger] = ss.str();
569
570       DALI_ASSERT_DEBUG( mCurrentLogger < mPerformanceLoggers.size() );
571       mPerformanceLoggers[mCurrentLogger] = Dali::PerformanceLogger::New( mPerformanceLoggerNames[mCurrentLogger].c_str() );
572
573       DALI_ASSERT_DEBUG( mCurrentLogger < mLoggerStates.size() );
574       mLoggerStates[mCurrentLogger].isTiming = false;
575       mLoggerStates[mCurrentLogger].isEnabled = true;
576       mLoggerStates[mCurrentLogger].frequency = MEDIUM_FREQUENCY;
577
578       UpdateState();
579     }
580     else if ( button.GetName() == DELETE_BUTTON_ID )
581     {
582       DALI_ASSERT_DEBUG( mCurrentLogger < mPerformanceLoggers.size() );
583       mPerformanceLoggers[mCurrentLogger].Reset();
584
585       DALI_ASSERT_DEBUG( mCurrentLogger < mLoggerStates.size() );
586       mLoggerStates[mCurrentLogger].isTiming = false;
587       mLoggerStates[mCurrentLogger].isEnabled = true;
588       mLoggerStates[mCurrentLogger].frequency = MEDIUM_FREQUENCY;
589
590       UpdateState();
591     }
592     else if ( button.GetName() == START_BUTTON_ID )
593     {
594       if( mPerformanceLoggers[mCurrentLogger] )
595       {
596         DALI_ASSERT_DEBUG( mCurrentLogger < mPerformanceLoggers.size() );
597         mPerformanceLoggers[mCurrentLogger].AddMarker( Dali::PerformanceLogger::START_EVENT );
598
599         DALI_ASSERT_DEBUG( mCurrentLogger < mLoggerStates.size() );
600         mLoggerStates[mCurrentLogger].isTiming = true;
601       }
602     }
603     else if ( button.GetName() == STOP_BUTTON_ID )
604     {
605       if( mPerformanceLoggers[mCurrentLogger] )
606       {
607         DALI_ASSERT_DEBUG( mCurrentLogger < mPerformanceLoggers.size() );
608         mPerformanceLoggers[mCurrentLogger].AddMarker( Dali::PerformanceLogger::END_EVENT );
609
610         DALI_ASSERT_DEBUG( mCurrentLogger < mLoggerStates.size() );
611         mLoggerStates[mCurrentLogger].isTiming = false;
612       }
613     }
614     else if ( button.GetName() == ENABLE_BUTTON_ID )
615     {
616       if( mPerformanceLoggers[mCurrentLogger] )
617       {
618         DALI_ASSERT_DEBUG( mCurrentLogger < mPerformanceLoggers.size() );
619         mPerformanceLoggers[mCurrentLogger].EnableLogging( true );
620
621         DALI_ASSERT_DEBUG( mCurrentLogger < mLoggerStates.size() );
622         mLoggerStates[mCurrentLogger].isEnabled = true;
623       }
624     }
625     else if ( button.GetName() == DISABLE_BUTTON_ID )
626     {
627       if( mPerformanceLoggers[mCurrentLogger] )
628       {
629         DALI_ASSERT_DEBUG( mCurrentLogger < mPerformanceLoggers.size() );
630         mPerformanceLoggers[mCurrentLogger].EnableLogging( false );
631
632         DALI_ASSERT_DEBUG( mCurrentLogger < mLoggerStates.size() );
633         mLoggerStates[mCurrentLogger].isEnabled = false;
634       }
635     }
636
637     WriteConsole();
638
639     return true;
640   }
641
642   bool OnTouchEvent( Actor actor, const TouchEvent& event )
643   {
644     if( 1u == event.GetPointCount() )
645     {
646       const TouchPoint::State state = event.GetPoint(0u).state;
647
648       // Clamp to integer values; this is to reduce flicking due to pixel misalignment
649       const float localPoint = static_cast<float>( static_cast<int>( event.GetPoint( 0 ).local.y ) );
650
651       if( TouchPoint::Down == state )
652       {
653         mLastPoint = localPoint;
654         mAnimation = Animation::New( 0.25f );
655       }
656       else if( TouchPoint::Motion == state )
657       {
658         if( mAnimation )
659         {
660           mAnimation.AnimateBy( Property(actor, Actor::Property::POSITION), Vector3( 0.f, localPoint - mLastPoint, 0.f ), AlphaFunction::LINEAR );
661           mAnimation.Play();
662           mLastPoint = localPoint;
663         }
664       }
665     }
666
667     return true;
668   }
669
670  private:
671
672   struct LoggerState
673   {
674     LoggerState() : frequency( 0 ), isTiming( false ), isEnabled( true ) {}
675
676     unsigned int frequency;
677     bool isTiming;
678     bool isEnabled;
679   };
680
681   Application&      mApplication;
682   Toolkit::Control  mView;                   ///< The View instance.
683   Toolkit::ToolBar  mToolBar;                ///< The View's Toolbar.
684   Layer             mContentLayer;           ///< Content layer
685
686   Animation      mAnimation;
687   float          mLastPoint;
688
689   typedef std::vector< std::string > Strings;
690   Strings mPerformanceLoggerNames;
691
692   typedef std::vector< Dali::PerformanceLogger > PerformanceLoggers;
693   PerformanceLoggers mPerformanceLoggers;
694   unsigned int mCurrentLogger;
695
696   typedef std::vector< LoggerState > LoggerStates;
697   LoggerStates mLoggerStates;
698
699   typedef std::vector< Toolkit::RadioButton > RadioButtons;
700   RadioButtons mLogRadioButtons;
701   RadioButtons mFrequencyRadioButtons;
702 };
703
704 void RunTest( Application& application )
705 {
706   LoggingController test( application );
707
708   application.MainLoop();
709 }
710
711 // Entry point for Linux & Tizen applications
712 //
713 int DALI_EXPORT_API main( int argc, char **argv )
714 {
715   Application application = Application::New( &argc, &argv, DEMO_THEME_PATH );
716
717   RunTest( application );
718
719   return 0;
720 }