use modern construct '= default' for special functions.
[platform/core/uifw/dali-core.git] / dali / internal / common / message.h
1 #ifndef DALI_INTERNAL_MESSAGE_H
2 #define DALI_INTERNAL_MESSAGE_H
3
4 /*
5  * Copyright (c) 2019 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // INTERNAL INCLUDES
22 #include <dali/internal/common/buffer-index.h>
23 #include <dali/internal/common/type-abstraction.h>
24 #include <dali/internal/update/common/scene-graph-buffers.h>
25
26 namespace Dali
27 {
28
29 namespace Internal
30 {
31
32 /**
33  * An abstract base class for messages queued across threads.
34  * Messages are only allowed to contain value objects, either copies of the parameters or pointers
35  * If message parameter type is & or const& the message will try to take a copy of the actual type
36  */
37 class MessageBase
38 {
39 public:
40
41   /**
42    * Construct the message base.
43    */
44   MessageBase() = default;
45
46   /**
47    * Virtual destructor
48    */
49   virtual ~MessageBase() = default;
50
51   /**
52    * Called to process the message.
53    * @param [in] bufferIndex The current update/render buffer index (depending on which thread processes the message).
54    */
55   virtual void Process( BufferIndex bufferIndex ) = 0;
56
57 private:
58 };
59
60 /**
61  * Templated message which calls a member function of an object.
62  * This allows nodes etc. to be modified in a thread-safe manner, when the update occurs in a separate thread.
63  * The object lifetime must controlled i.e. not destroyed before the message is processed.
64  */
65 template< typename T >
66 class Message : public MessageBase
67 {
68 public:
69   using MemberFunction = void ( T::* )();
70
71   /**
72    * Create a message.
73    * @note The object is expected to be const in the thread which sends this message.
74    * However it can be modified when Process() is called in a different thread.
75    * @param[in] obj The object to be updated in a separate thread.
76    * @param[in] member The member function of the object.
77    */
78   Message( const T* obj, MemberFunction member )
79   : MessageBase(),
80     object( const_cast< T* >( obj ) ),
81     memberFunction( member )
82   {
83     DALI_ASSERT_DEBUG( object && "nullptr passed into message as object" );
84   }
85
86   /**
87    * Virtual destructor
88    */
89   ~Message() override = default;
90
91   /**
92    * @copydoc MessageBase::Process
93    */
94   void Process( BufferIndex /*bufferIndex*/ ) override
95   {
96     (object->*memberFunction)();
97   }
98
99 private:
100
101   T* object;
102   MemberFunction memberFunction;
103
104 };
105
106 /**
107  * Templated message which calls a member function of an object.
108  * This overload passes one value-type parameter.
109  * Template parameters need to match the MemberFunction!
110  * The message will contain copy of the value (in case of & or const&)
111  */
112 template< typename T, typename P >
113 class MessageValue1 : public MessageBase
114 {
115 public:
116   using MemberFunction = void ( T::* )( typename ParameterType<P>::PassingType );
117
118   /**
119    * Create a message.
120    * @note The object is expected to be const in the thread which sends this message.
121    * However it can be modified when Process() is called in a different thread.
122    * @param[in] obj The object.
123    * @param[in] member The member function of the object.
124    * @param[in] p1 The first value-type parameter to pass to the member function.
125    */
126   MessageValue1( const T* obj,
127                  MemberFunction member,
128                  typename ParameterType< P >::PassingType p1 )
129   : MessageBase(),
130     object( const_cast< T* >( obj ) ),
131     memberFunction( member ),
132     param1( p1 )
133   {
134     DALI_ASSERT_DEBUG( object && "nullptr passed into message as object" );
135   }
136
137   /**
138    * Virtual destructor
139    */
140   ~MessageValue1() override = default;
141
142   /**
143    * @copydoc MessageBase::Process
144    */
145   void Process( BufferIndex /*bufferIndex*/ ) override
146   {
147     (object->*memberFunction)( param1 );
148   }
149
150 private:
151
152   T* object;
153   MemberFunction memberFunction;
154   typename ParameterType< P >::HolderType param1;
155
156 };
157
158 /**
159  * Templated message which calls a member function of an object.
160  * This overload passes two value-type parameters.
161  * Template parameters need to match the MemberFunction!
162  * The message will contain copy of the value (in case of & or const&)
163  */
164
165 template< typename T, typename P1, typename P2 >
166 class MessageValue2 : public MessageBase
167 {
168 public:
169   using MemberFunction = void ( T::* )( typename ParameterType<P1>::PassingType, typename ParameterType<P2>::PassingType );
170
171   /**
172    * Create a message.
173    * @note The object is expected to be const in the thread which sends this message.
174    * However it can be modified when Process() is called in a different thread.
175    * @param[in] obj The object.
176    * @param[in] member The member function of the object.
177    * @param[in] p1 The first parameter to pass to the member function.
178    * @param[in] p2 The second parameter to pass to the member function.
179    */
180   MessageValue2( const T* obj,
181                  MemberFunction member,
182                  typename ParameterType< P1 >::PassingType p1,
183                  typename ParameterType< P2 >::PassingType p2 )
184   : MessageBase(),
185     object( const_cast< T* >( obj ) ),
186     memberFunction( member ),
187     param1( p1 ),
188     param2( p2 )
189   {
190     DALI_ASSERT_DEBUG( object && "nullptr passed into message as object" );
191   }
192
193   /**
194    * Virtual destructor
195    */
196   ~MessageValue2() override = default;
197
198   /**
199    * @copydoc MessageBase::Process
200    */
201   void Process( BufferIndex /*bufferIndex*/ ) override
202   {
203     (object->*memberFunction)( param1, param2 );
204   }
205
206 private:
207
208   T* object;
209   MemberFunction memberFunction;
210   typename ParameterType< P1 >::HolderType param1;
211   typename ParameterType< P2 >::HolderType param2;
212
213 };
214
215 /**
216  * Templated message which calls a member function of an object.
217  * This overload passes three value-type parameters.
218  * Template parameters need to match the MemberFunction!
219  * The message will contain copy of the value (in case of & or const&)
220  */
221 template< typename T, typename P1, typename P2, typename P3 >
222 class MessageValue3 : public MessageBase
223 {
224 public:
225   using MemberFunction = void ( T::* )( typename ParameterType<P1>::PassingType, typename ParameterType<P2>::PassingType, typename ParameterType<P3>::PassingType );
226
227   /**
228    * Create a message.
229    * @note The object is expected to be const in the thread which sends this message.
230    * However it can be modified when Process() is called in a different thread.
231    * @param[in] obj The object.
232    * @param[in] member The member function of the object.
233    * @param[in] p1 The first parameter to pass to the member function.
234    * @param[in] p2 The second parameter to pass to the member function.
235    * @param[in] p3 The third parameter to pass to the member function.
236    */
237   MessageValue3( const T* obj,
238                  MemberFunction member,
239                  typename ParameterType< P1 >::PassingType p1,
240                  typename ParameterType< P2 >::PassingType p2,
241                  typename ParameterType< P3 >::PassingType p3 )
242   : MessageBase(),
243     object( const_cast< T* >( obj ) ),
244     memberFunction( member ),
245     param1( p1 ),
246     param2( p2 ),
247     param3( p3 )
248   {
249     DALI_ASSERT_DEBUG( object && "nullptr passed into message as object" );
250   }
251
252   /**
253    * Virtual destructor
254    */
255   ~MessageValue3() override = default;
256
257   /**
258    * @copydoc MessageBase::Process
259    */
260   void Process( BufferIndex /*bufferIndex*/ ) override
261   {
262     (object->*memberFunction)( param1, param2, param3 );
263   }
264
265 private:
266
267   T* object;
268   MemberFunction memberFunction;
269   typename ParameterType< P1 >::HolderType param1;
270   typename ParameterType< P2 >::HolderType param2;
271   typename ParameterType< P3 >::HolderType param3;
272
273 };
274
275 /**
276  * Templated message which calls a member function of an object.
277  * This overload passes four value-type parameters.
278  * Template parameters need to match the MemberFunction!
279  * The message will contain copy of the value (in case of & or const&)
280  */
281 template< typename T, typename P1, typename P2, typename P3, typename P4 >
282 class MessageValue4 : public MessageBase
283 {
284 public:
285   using MemberFunction = void ( T::* )( typename ParameterType<P1>::PassingType, typename ParameterType<P2>::PassingType, typename ParameterType<P3>::PassingType, typename ParameterType<P4>::PassingType );
286
287   /**
288    * Create a message.
289    * @note The object is expected to be const in the thread which sends this message.
290    * However it can be modified when Process() is called in a different thread.
291    * @param[in] obj The object.
292    * @param[in] member The member function of the object.
293    * @param[in] p1 The first parameter to pass to the member function.
294    * @param[in] p2 The second parameter to pass to the member function.
295    * @param[in] p3 The third parameter to pass to the member function.
296    * @param[in] p4 The fourth parameter to pass to the member function.
297    */
298   MessageValue4( const T* obj,
299                  MemberFunction member,
300                  typename ParameterType< P1 >::PassingType p1,
301                  typename ParameterType< P2 >::PassingType p2,
302                  typename ParameterType< P3 >::PassingType p3,
303                  typename ParameterType< P4 >::PassingType p4 )
304   : MessageBase(),
305     object( const_cast< T* >( obj ) ),
306     memberFunction( member ),
307     param1( p1 ),
308     param2( p2 ),
309     param3( p3 ),
310     param4( p4 )
311   {
312     DALI_ASSERT_DEBUG( object && "nullptr passed into message as object" );
313   }
314
315   /**
316    * Virtual destructor
317    */
318   ~MessageValue4() override = default;
319
320   /**
321    * @copydoc MessageBase::Process
322    */
323   void Process( BufferIndex /*bufferIndex*/ ) override
324   {
325     (object->*memberFunction)( param1, param2, param3, param4 );
326   }
327
328 private:
329
330   T* object;
331   MemberFunction memberFunction;
332   typename ParameterType< P1 >::HolderType param1;
333   typename ParameterType< P2 >::HolderType param2;
334   typename ParameterType< P3 >::HolderType param3;
335   typename ParameterType< P4 >::HolderType param4;
336
337 };
338
339 /**
340  * Templated message which calls a member function of an object.
341  * This overload passes five value-type parameters.
342  * Template parameters need to match the MemberFunction!
343  * The message will contain copy of the value (in case of & or const&)
344  */
345 template< typename T, typename P1, typename P2, typename P3, typename P4, typename P5 >
346 class MessageValue5 : public MessageBase
347 {
348 public:
349   using MemberFunction = void ( T::* )( typename ParameterType<P1>::PassingType, typename ParameterType<P2>::PassingType, typename ParameterType<P3>::PassingType, typename ParameterType<P4>::PassingType, typename ParameterType<P5>::PassingType );
350
351   /**
352    * Create a message.
353    * @note The object is expected to be const in the thread which sends this message.
354    * However it can be modified when Process() is called in a different thread.
355    * @param[in] obj The object.
356    * @param[in] member The member function of the object.
357    * @param[in] p1 The first parameter to pass to the member function.
358    * @param[in] p2 The second parameter to pass to the member function.
359    * @param[in] p3 The third parameter to pass to the member function.
360    * @param[in] p4 The fourth parameter to pass to the member function.
361    * @param[in] p5 The fifth parameter to pass to the member function.
362    */
363   MessageValue5( const T* obj,
364                  MemberFunction member,
365                  typename ParameterType< P1 >::PassingType p1,
366                  typename ParameterType< P2 >::PassingType p2,
367                  typename ParameterType< P3 >::PassingType p3,
368                  typename ParameterType< P4 >::PassingType p4,
369                  typename ParameterType< P5 >::PassingType p5 )
370   : MessageBase(),
371     object( const_cast< T* >( obj ) ),
372     memberFunction( member ),
373     param1( p1 ),
374     param2( p2 ),
375     param3( p3 ),
376     param4( p4 ),
377     param5( p5 )
378   {
379     DALI_ASSERT_DEBUG( object && "nullptr passed into message as object" );
380   }
381
382   /**
383    * Virtual destructor
384    */
385   ~MessageValue5() override = default;
386
387   /**
388    * @copydoc MessageBase::Process
389    */
390   void Process( BufferIndex /*bufferIndex*/ ) override
391   {
392     (object->*memberFunction)( param1, param2, param3, param4, param5 );
393   }
394
395 private:
396
397   T* object;
398   MemberFunction memberFunction;
399   typename ParameterType< P1 >::HolderType param1;
400   typename ParameterType< P2 >::HolderType param2;
401   typename ParameterType< P3 >::HolderType param3;
402   typename ParameterType< P4 >::HolderType param4;
403   typename ParameterType< P5 >::HolderType param5;
404
405 };
406
407 /**
408  * Templated message which calls a member function of an object.
409  * This overload passes six value-type parameters.
410  * Template parameters need to match the MemberFunction!
411  * The message will contain copy of the value (in case of & or const&)
412  */
413 template< typename T, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6 >
414 class MessageValue6 : public MessageBase
415 {
416 public:
417   using MemberFunction = void ( T::* )( typename ParameterType<P1>::PassingType, typename ParameterType<P2>::PassingType, typename ParameterType<P3>::PassingType, typename ParameterType<P4>::PassingType, typename ParameterType<P5>::PassingType, typename ParameterType<P6>::PassingType );
418
419   /**
420    * Create a message.
421    * @note The object is expected to be const in the thread which sends this message.
422    * However it can be modified when Process() is called in a different thread.
423    * @param[in] obj The object.
424    * @param[in] member The member function of the object.
425    * @param[in] p1 The first parameter to pass to the member function.
426    * @param[in] p2 The second parameter to pass to the member function.
427    * @param[in] p3 The third parameter to pass to the member function.
428    * @param[in] p4 The fourth parameter to pass to the member function.
429    * @param[in] p5 The fifth parameter to pass to the member function.
430    * @param[in] p6 The sixth parameter to pass to the member function.
431    */
432   MessageValue6( const T* obj,
433                  MemberFunction member,
434                  typename ParameterType< P1 >::PassingType p1,
435                  typename ParameterType< P2 >::PassingType p2,
436                  typename ParameterType< P3 >::PassingType p3,
437                  typename ParameterType< P4 >::PassingType p4,
438                  typename ParameterType< P5 >::PassingType p5,
439                  typename ParameterType< P6 >::PassingType p6 )
440   : MessageBase(),
441     object( const_cast< T* >( obj ) ),
442     memberFunction( member ),
443     param1( p1 ),
444     param2( p2 ),
445     param3( p3 ),
446     param4( p4 ),
447     param5( p5 ),
448     param6( p6 )
449   {
450     DALI_ASSERT_DEBUG( object && "nullptr passed into message as object" );
451   }
452
453   /**
454    * Virtual destructor
455    */
456   ~MessageValue6() override = default;
457
458   /**
459    * @copydoc MessageBase::Process
460    */
461   void Process( BufferIndex /*bufferIndex*/ ) override
462   {
463     (object->*memberFunction)( param1, param2, param3, param4, param5, param6 );
464   }
465
466 private:
467
468   T* object;
469   MemberFunction memberFunction;
470   typename ParameterType< P1 >::HolderType param1;
471   typename ParameterType< P2 >::HolderType param2;
472   typename ParameterType< P3 >::HolderType param3;
473   typename ParameterType< P4 >::HolderType param4;
474   typename ParameterType< P5 >::HolderType param5;
475   typename ParameterType< P6 >::HolderType param6;
476
477 };
478
479 /**
480  * Templated message which calls a member function of an object.
481  * This overload passes just the buffer index to the method, no parameters.
482  */
483 template< typename T >
484 class MessageDoubleBuffered0 : public MessageBase
485 {
486 public:
487   using MemberFunction = void ( T::* )( BufferIndex );
488
489   /**
490    * Create a message.
491    * @note The object is expected to be const in the thread which sends this message.
492    * However it can be modified when Process() is called in a different thread.
493    * @param[in] obj The object.
494    * @param[in] member The member function of the object.
495    */
496   MessageDoubleBuffered0( const T* obj, MemberFunction member )
497   : MessageBase(),
498     object( const_cast< T* >( obj ) ),
499     memberFunction( member )
500   {
501     DALI_ASSERT_DEBUG( object && "nullptr passed into message as object" );
502   }
503
504   /**
505    * Virtual destructor
506    */
507   ~MessageDoubleBuffered0() override = default;
508
509   /**
510    * @copydoc MessageBase::Process
511    */
512   void Process( BufferIndex bufferIndex ) override
513   {
514     (object->*memberFunction)( bufferIndex );
515   }
516
517 private:
518
519   T* object;
520   MemberFunction memberFunction;
521
522 };
523
524
525 /**
526  * Templated message which calls a member function of an object.
527  * This overload passes a value-type to set a double-buffered property.
528  * Template parameters need to match the MemberFunction!
529  * The message will contain copy of the value (in case of & or const&)
530  */
531 template< typename T, typename P >
532 class MessageDoubleBuffered1 : public MessageBase
533 {
534 public:
535   using MemberFunction = void ( T::* )( BufferIndex, typename ParameterType<P>::PassingType );
536
537   /**
538    * Create a message.
539    * @note The object is expected to be const in the thread which sends this message.
540    * However it can be modified when Process() is called in a different thread.
541    * @param[in] obj The object.
542    * @param[in] member The member function of the object.
543    * @param[in] p The second parameter to pass.
544    */
545   MessageDoubleBuffered1( const T* obj,
546                           MemberFunction member,
547                           typename ParameterType< P >::PassingType p )
548   : MessageBase(),
549     object( const_cast< T* >( obj ) ),
550     memberFunction( member ),
551     param( p )
552   {
553     DALI_ASSERT_DEBUG( object && "nullptr passed into message as object" );
554   }
555
556   /**
557    * Virtual destructor
558    */
559   ~MessageDoubleBuffered1() override = default;
560
561   /**
562    * @copydoc MessageBase::Process
563    */
564   void Process( BufferIndex bufferIndex ) override
565   {
566     (object->*memberFunction)( bufferIndex,  param );
567   }
568
569 private:
570
571   T* object;
572   MemberFunction memberFunction;
573   typename ParameterType< P >::HolderType param;
574
575 };
576
577 /**
578  * Templated message which calls a member function of an object.
579  * This overload passes two value-types to set double-buffered properties.
580  * Template parameters need to match the MemberFunction!
581  * The message will contain copy of the value (in case of & or const&)
582  */
583 template< typename T, typename P2, typename P3 >
584 class MessageDoubleBuffered2 : public MessageBase
585 {
586 public:
587   using MemberFunction = void ( T::* )( BufferIndex, typename ParameterType<P2>::PassingType, typename ParameterType<P3>::PassingType );
588
589   /**
590    * Create a message.
591    * @note The object is expected to be const in the thread which sends this message.
592    * However it can be modified when Process() is called in a different thread.
593    * @param[in] obj The object.
594    * @param[in] member The member function of the object.
595    * @param[in] p2 The second parameter to pass to the function.
596    * @param[in] p3 The third parameter to pass to the function.
597    */
598   MessageDoubleBuffered2( const T* obj,
599                           MemberFunction member,
600                           typename ParameterType< P2 >::PassingType p2,
601                           typename ParameterType< P3 >::PassingType p3 )
602   : MessageBase(),
603     object( const_cast< T* >( obj ) ),
604     memberFunction( member ),
605     param2( p2 ),
606     param3( p3 )
607   {
608     DALI_ASSERT_DEBUG( object && "nullptr passed into message as object" );
609   }
610
611   /**
612    * Virtual destructor
613    */
614   ~MessageDoubleBuffered2() override = default;
615
616   /**
617    * @copydoc MessageBase::Process
618    */
619   void Process( BufferIndex bufferIndex ) override
620   {
621     (object->*memberFunction)( bufferIndex, param2, param3 );
622   }
623
624 private:
625
626   T* object;
627   MemberFunction memberFunction;
628   typename ParameterType< P2 >::HolderType param2;
629   typename ParameterType< P3 >::HolderType param3;
630
631 };
632
633
634 /**
635  * Templated message which calls a member function of an object.
636  * This overload passes three value-types to set double-buffered properties.
637  * Template parameters need to match the MemberFunction!
638  * The message will contain copy of the value (in case of & or const&)
639  */
640 template< typename T, typename P2, typename P3, typename P4 >
641 class MessageDoubleBuffered3 : public MessageBase
642 {
643 public:
644   using MemberFunction = void ( T::* )( BufferIndex, typename ParameterType<P2>::PassingType, typename ParameterType<P3>::PassingType, typename ParameterType<P4>::PassingType );
645
646   /**
647    * Create a message.
648    * @note The object is expected to be const in the thread which sends this message.
649    * However it can be modified when Process() is called in a different thread.
650    * @param[in] obj The object.
651    * @param[in] member The member function of the object.
652    * @param[in] p2 The second parameter to pass.
653    * @param[in] p3 The third parameter to pass.
654    * @param[in] p4 The forth parameter to pass.
655    */
656   MessageDoubleBuffered3( const T* obj,
657                           MemberFunction member,
658                           typename ParameterType< P2 >::PassingType p2,
659                           typename ParameterType< P3 >::PassingType p3,
660                           typename ParameterType< P4 >::PassingType p4 )
661   : MessageBase(),
662     object( const_cast< T* >( obj ) ),
663     memberFunction( member ),
664     param2( p2 ),
665     param3( p3 ),
666     param4( p4 )
667   {
668     DALI_ASSERT_DEBUG( object && "nullptr passed into message as object" );
669   }
670
671   /**
672    * Virtual destructor
673    */
674   ~MessageDoubleBuffered3() override = default;
675
676   /**
677    * @copydoc MessageBase::Process
678    */
679   void Process( BufferIndex bufferIndex ) override
680   {
681     (object->*memberFunction)( bufferIndex, param2, param3, param4 );
682   }
683
684 private:
685
686   T* object;
687   MemberFunction memberFunction;
688   typename ParameterType< P2 >::HolderType param2;
689   typename ParameterType< P3 >::HolderType param3;
690   typename ParameterType< P4 >::HolderType param4;
691
692 };
693
694 /**
695  * Templated message which calls a member function of an object.
696  * This overload passes four value-types to set double-buffered properties.
697  * Template parameters need to match the MemberFunction!
698  * The message will contain copy of the value (in case of & or const&)
699  */
700 template< typename T, typename P2, typename P3, typename P4, typename P5 >
701 class MessageDoubleBuffered4 : public MessageBase
702 {
703 public:
704   using MemberFunction = void ( T::* )( BufferIndex, typename ParameterType<P2>::PassingType, typename ParameterType<P3>::PassingType, typename ParameterType<P4>::PassingType, typename ParameterType<P5>::PassingType );
705
706   /**
707    * Create a message.
708    * @note The object is expected to be const in the thread which sends this message.
709    * However it can be modified when Process() is called in a different thread.
710    * @param[in] obj The object.
711    * @param[in] member The member function of the object.
712    * @param[in] p2 The second parameter to pass.
713    * @param[in] p3 The third parameter to pass.
714    * @param[in] p4 The forth parameter to pass.
715    * @param[in] p5 The fifth parameter to pass.
716    */
717   MessageDoubleBuffered4( const T* obj,
718                           MemberFunction member,
719                           typename ParameterType< P2 >::PassingType p2,
720                           typename ParameterType< P3 >::PassingType p3,
721                           typename ParameterType< P4 >::PassingType p4,
722                           typename ParameterType< P5 >::PassingType p5 )
723   : MessageBase(),
724     object( const_cast< T* >( obj ) ),
725     memberFunction( member ),
726     param2( p2 ),
727     param3( p3 ),
728     param4( p4 ),
729     param5( p5 )
730   {
731     DALI_ASSERT_DEBUG( object && "nullptr passed into message as object" );
732   }
733
734   /**
735    * Virtual destructor
736    */
737   ~MessageDoubleBuffered4() override = default;
738
739   /**
740    * @copydoc MessageBase::Process
741    */
742   void Process( BufferIndex bufferIndex ) override
743   {
744     (object->*memberFunction)( bufferIndex, param2, param3, param4, param5 );
745   }
746
747 private:
748
749   T* object;
750   MemberFunction memberFunction;
751   typename ParameterType< P2 >::HolderType param2;
752   typename ParameterType< P3 >::HolderType param3;
753   typename ParameterType< P4 >::HolderType param4;
754   typename ParameterType< P5 >::HolderType param5;
755
756 };
757
758 } // namespace Internal
759
760 } // namespace Dali
761
762 #endif // DALI_INTERNAL_MESSAGE_H