73ad04a0a6b8f3e5274a7e4ed7248d12edd3a057
[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) 2017 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( )
45   {
46   }
47
48   /**
49    * Virtual destructor
50    */
51   virtual ~MessageBase()
52   {
53   }
54
55   /**
56    * Called to process the message.
57    * @param [in] bufferIndex The current update/render buffer index (depending on which thread processes the message).
58    */
59   virtual void Process( BufferIndex bufferIndex ) = 0;
60
61 private:
62 };
63
64 /**
65  * Templated message which calls a member function of an object.
66  * This allows nodes etc. to be modified in a thread-safe manner, when the update occurs in a separate thread.
67  * The object lifetime must controlled i.e. not destroyed before the message is processed.
68  */
69 template< typename T >
70 class Message : public MessageBase
71 {
72 public:
73
74   typedef void(T::*MemberFunction)();
75
76   /**
77    * Create a message.
78    * @note The object is expected to be const in the thread which sends this message.
79    * However it can be modified when Process() is called in a different thread.
80    * @param[in] obj The object to be updated in a separate thread.
81    * @param[in] member The member function of the object.
82    */
83   Message( const T* obj, MemberFunction member )
84   : MessageBase(),
85     object( const_cast< T* >( obj ) ),
86     memberFunction( member )
87   {
88   }
89
90   /**
91    * Virtual destructor
92    */
93   virtual ~Message()
94   {
95   }
96
97   /**
98    * @copydoc MessageBase::Process
99    */
100   virtual void Process( BufferIndex /*bufferIndex*/ )
101   {
102     DALI_ASSERT_DEBUG( object && "Message does not have an object" );
103     (object->*memberFunction)();
104   }
105
106 private:
107
108   T* object;
109   MemberFunction memberFunction;
110
111 };
112
113 /**
114  * Templated message which calls a member function of an object.
115  * This overload passes one value-type parameter.
116  * Template parameters need to match the MemberFunction!
117  * The message will contain copy of the value (in case of & or const&)
118  */
119 template< typename T, typename P >
120 class MessageValue1 : public MessageBase
121 {
122 public:
123
124   typedef void(T::*MemberFunction)( typename ParameterType< P >::PassingType );
125
126   /**
127    * Create a message.
128    * @note The object is expected to be const in the thread which sends this message.
129    * However it can be modified when Process() is called in a different thread.
130    * @param[in] obj The object.
131    * @param[in] member The member function of the object.
132    * @param[in] p1 The first value-type parameter to pass to the member function.
133    */
134   MessageValue1( const T* obj,
135                  MemberFunction member,
136                  typename ParameterType< P >::PassingType p1 )
137   : MessageBase(),
138     object( const_cast< T* >( obj ) ),
139     memberFunction( member ),
140     param1( p1 )
141   {
142   }
143
144   /**
145    * Virtual destructor
146    */
147   virtual ~MessageValue1()
148   {
149   }
150
151   /**
152    * @copydoc MessageBase::Process
153    */
154   virtual void Process( BufferIndex /*bufferIndex*/ )
155   {
156     DALI_ASSERT_DEBUG( object && "Message does not have an object" );
157     (object->*memberFunction)( param1 );
158   }
159
160 private:
161
162   T* object;
163   MemberFunction memberFunction;
164   typename ParameterType< P >::HolderType param1;
165
166 };
167
168 /**
169  * Templated message which calls a member function of an object.
170  * This overload passes two value-type parameters.
171  * Template parameters need to match the MemberFunction!
172  * The message will contain copy of the value (in case of & or const&)
173  */
174
175 template< typename T, typename P1, typename P2 >
176 class MessageValue2 : public MessageBase
177 {
178 public:
179
180   typedef void(T::*MemberFunction)(
181       typename ParameterType< P1 >::PassingType,
182       typename ParameterType< P2 >::PassingType );
183
184   /**
185    * Create a message.
186    * @note The object is expected to be const in the thread which sends this message.
187    * However it can be modified when Process() is called in a different thread.
188    * @param[in] obj The object.
189    * @param[in] member The member function of the object.
190    * @param[in] p1 The first parameter to pass to the member function.
191    * @param[in] p2 The second parameter to pass to the member function.
192    */
193   MessageValue2( const T* obj,
194                  MemberFunction member,
195                  typename ParameterType< P1 >::PassingType p1,
196                  typename ParameterType< P2 >::PassingType p2 )
197   : MessageBase(),
198     object( const_cast< T* >( obj ) ),
199     memberFunction( member ),
200     param1( p1 ),
201     param2( p2 )
202   {
203   }
204
205   /**
206    * Virtual destructor
207    */
208   virtual ~MessageValue2()
209   {
210   }
211
212   /**
213    * @copydoc MessageBase::Process
214    */
215   virtual void Process( BufferIndex /*bufferIndex*/ )
216   {
217     DALI_ASSERT_DEBUG( object && "Message does not have an object" );
218     (object->*memberFunction)( param1, param2 );
219   }
220
221 private:
222
223   T* object;
224   MemberFunction memberFunction;
225   typename ParameterType< P1 >::HolderType param1;
226   typename ParameterType< P2 >::HolderType param2;
227
228 };
229
230 /**
231  * Templated message which calls a member function of an object.
232  * This overload passes three value-type parameters.
233  * Template parameters need to match the MemberFunction!
234  * The message will contain copy of the value (in case of & or const&)
235  */
236 template< typename T, typename P1, typename P2, typename P3 >
237 class MessageValue3 : public MessageBase
238 {
239 public:
240
241   typedef void(T::*MemberFunction)(
242       typename ParameterType< P1 >::PassingType,
243       typename ParameterType< P2 >::PassingType,
244       typename ParameterType< P3 >::PassingType );
245
246   /**
247    * Create a message.
248    * @note The object is expected to be const in the thread which sends this message.
249    * However it can be modified when Process() is called in a different thread.
250    * @param[in] obj The object.
251    * @param[in] member The member function of the object.
252    * @param[in] p1 The first parameter to pass to the member function.
253    * @param[in] p2 The second parameter to pass to the member function.
254    * @param[in] p3 The third parameter to pass to the member function.
255    */
256   MessageValue3( const T* obj,
257                  MemberFunction member,
258                  typename ParameterType< P1 >::PassingType p1,
259                  typename ParameterType< P2 >::PassingType p2,
260                  typename ParameterType< P3 >::PassingType p3 )
261   : MessageBase(),
262     object( const_cast< T* >( obj ) ),
263     memberFunction( member ),
264     param1( p1 ),
265     param2( p2 ),
266     param3( p3 )
267   {
268   }
269
270   /**
271    * Virtual destructor
272    */
273   virtual ~MessageValue3()
274   {
275   }
276
277   /**
278    * @copydoc MessageBase::Process
279    */
280   virtual void Process( BufferIndex /*bufferIndex*/ )
281   {
282     DALI_ASSERT_DEBUG( object && "Message does not have an object" );
283     (object->*memberFunction)( param1, param2, param3 );
284   }
285
286 private:
287
288   T* object;
289   MemberFunction memberFunction;
290   typename ParameterType< P1 >::HolderType param1;
291   typename ParameterType< P2 >::HolderType param2;
292   typename ParameterType< P3 >::HolderType param3;
293
294 };
295
296 /**
297  * Templated message which calls a member function of an object.
298  * This overload passes four value-type parameters.
299  * Template parameters need to match the MemberFunction!
300  * The message will contain copy of the value (in case of & or const&)
301  */
302 template< typename T, typename P1, typename P2, typename P3, typename P4 >
303 class MessageValue4 : public MessageBase
304 {
305 public:
306
307   typedef void(T::*MemberFunction)(
308       typename ParameterType< P1 >::PassingType,
309       typename ParameterType< P2 >::PassingType,
310       typename ParameterType< P3 >::PassingType,
311       typename ParameterType< P4 >::PassingType );
312
313   /**
314    * Create a message.
315    * @note The object is expected to be const in the thread which sends this message.
316    * However it can be modified when Process() is called in a different thread.
317    * @param[in] obj The object.
318    * @param[in] member The member function of the object.
319    * @param[in] p1 The first parameter to pass to the member function.
320    * @param[in] p2 The second parameter to pass to the member function.
321    * @param[in] p3 The third parameter to pass to the member function.
322    * @param[in] p4 The fourth parameter to pass to the member function.
323    */
324   MessageValue4( const T* obj,
325                  MemberFunction member,
326                  typename ParameterType< P1 >::PassingType p1,
327                  typename ParameterType< P2 >::PassingType p2,
328                  typename ParameterType< P3 >::PassingType p3,
329                  typename ParameterType< P4 >::PassingType p4 )
330   : MessageBase(),
331     object( const_cast< T* >( obj ) ),
332     memberFunction( member ),
333     param1( p1 ),
334     param2( p2 ),
335     param3( p3 ),
336     param4( p4 )
337   {
338   }
339
340   /**
341    * Virtual destructor
342    */
343   virtual ~MessageValue4()
344   {
345   }
346
347   /**
348    * @copydoc MessageBase::Process
349    */
350   virtual void Process( BufferIndex /*bufferIndex*/ )
351   {
352     DALI_ASSERT_DEBUG( object && "Message does not have an object" );
353     (object->*memberFunction)( param1, param2, param3, param4 );
354   }
355
356 private:
357
358   T* object;
359   MemberFunction memberFunction;
360   typename ParameterType< P1 >::HolderType param1;
361   typename ParameterType< P2 >::HolderType param2;
362   typename ParameterType< P3 >::HolderType param3;
363   typename ParameterType< P4 >::HolderType param4;
364
365 };
366
367 /**
368  * Templated message which calls a member function of an object.
369  * This overload passes five value-type parameters.
370  * Template parameters need to match the MemberFunction!
371  * The message will contain copy of the value (in case of & or const&)
372  */
373 template< typename T, typename P1, typename P2, typename P3, typename P4, typename P5 >
374 class MessageValue5 : public MessageBase
375 {
376 public:
377
378   typedef void(T::*MemberFunction)(
379       typename ParameterType< P1 >::PassingType,
380       typename ParameterType< P2 >::PassingType,
381       typename ParameterType< P3 >::PassingType,
382       typename ParameterType< P4 >::PassingType,
383       typename ParameterType< P5 >::PassingType );
384
385   /**
386    * Create a message.
387    * @note The object is expected to be const in the thread which sends this message.
388    * However it can be modified when Process() is called in a different thread.
389    * @param[in] obj The object.
390    * @param[in] member The member function of the object.
391    * @param[in] p1 The first parameter to pass to the member function.
392    * @param[in] p2 The second parameter to pass to the member function.
393    * @param[in] p3 The third parameter to pass to the member function.
394    * @param[in] p4 The fourth parameter to pass to the member function.
395    * @param[in] p5 The fifth parameter to pass to the member function.
396    */
397   MessageValue5( const T* obj,
398                  MemberFunction member,
399                  typename ParameterType< P1 >::PassingType p1,
400                  typename ParameterType< P2 >::PassingType p2,
401                  typename ParameterType< P3 >::PassingType p3,
402                  typename ParameterType< P4 >::PassingType p4,
403                  typename ParameterType< P5 >::PassingType p5 )
404   : MessageBase(),
405     object( const_cast< T* >( obj ) ),
406     memberFunction( member ),
407     param1( p1 ),
408     param2( p2 ),
409     param3( p3 ),
410     param4( p4 ),
411     param5( p5 )
412   {
413   }
414
415   /**
416    * Virtual destructor
417    */
418   virtual ~MessageValue5()
419   {
420   }
421
422   /**
423    * @copydoc MessageBase::Process
424    */
425   virtual void Process( BufferIndex /*bufferIndex*/ )
426   {
427     DALI_ASSERT_DEBUG( object && "Message does not have an object" );
428     (object->*memberFunction)( param1, param2, param3, param4, param5 );
429
430   }
431
432 private:
433
434   T* object;
435   MemberFunction memberFunction;
436   typename ParameterType< P1 >::HolderType param1;
437   typename ParameterType< P2 >::HolderType param2;
438   typename ParameterType< P3 >::HolderType param3;
439   typename ParameterType< P4 >::HolderType param4;
440   typename ParameterType< P5 >::HolderType param5;
441
442 };
443
444 /**
445  * Templated message which calls a member function of an object.
446  * This overload passes six value-type parameters.
447  * Template parameters need to match the MemberFunction!
448  * The message will contain copy of the value (in case of & or const&)
449  */
450 template< typename T, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6 >
451 class MessageValue6 : public MessageBase
452 {
453 public:
454
455   typedef void(T::*MemberFunction)(
456       typename ParameterType< P1 >::PassingType,
457       typename ParameterType< P2 >::PassingType,
458       typename ParameterType< P3 >::PassingType,
459       typename ParameterType< P4 >::PassingType,
460       typename ParameterType< P5 >::PassingType,
461       typename ParameterType< P6 >::PassingType );
462
463   /**
464    * Create a message.
465    * @note The object is expected to be const in the thread which sends this message.
466    * However it can be modified when Process() is called in a different thread.
467    * @param[in] obj The object.
468    * @param[in] member The member function of the object.
469    * @param[in] p1 The first parameter to pass to the member function.
470    * @param[in] p2 The second parameter to pass to the member function.
471    * @param[in] p3 The third parameter to pass to the member function.
472    * @param[in] p4 The fourth parameter to pass to the member function.
473    * @param[in] p5 The fifth parameter to pass to the member function.
474    * @param[in] p6 The sixth parameter to pass to the member function.
475    */
476   MessageValue6( const T* obj,
477                  MemberFunction member,
478                  typename ParameterType< P1 >::PassingType p1,
479                  typename ParameterType< P2 >::PassingType p2,
480                  typename ParameterType< P3 >::PassingType p3,
481                  typename ParameterType< P4 >::PassingType p4,
482                  typename ParameterType< P5 >::PassingType p5,
483                  typename ParameterType< P6 >::PassingType p6 )
484   : MessageBase(),
485     object( const_cast< T* >( obj ) ),
486     memberFunction( member ),
487     param1( p1 ),
488     param2( p2 ),
489     param3( p3 ),
490     param4( p4 ),
491     param5( p5 ),
492     param6( p6 )
493   {
494   }
495
496   /**
497    * Virtual destructor
498    */
499   virtual ~MessageValue6()
500   {
501   }
502
503   /**
504    * @copydoc MessageBase::Process
505    */
506   virtual void Process( BufferIndex /*bufferIndex*/ )
507   {
508     DALI_ASSERT_DEBUG( object && "Message does not have an object" );
509     (object->*memberFunction)( param1, param2, param3, param4, param5, param6 );
510
511   }
512
513 private:
514
515   T* object;
516   MemberFunction memberFunction;
517   typename ParameterType< P1 >::HolderType param1;
518   typename ParameterType< P2 >::HolderType param2;
519   typename ParameterType< P3 >::HolderType param3;
520   typename ParameterType< P4 >::HolderType param4;
521   typename ParameterType< P5 >::HolderType param5;
522   typename ParameterType< P6 >::HolderType param6;
523
524 };
525
526 /**
527  * Templated message which calls a member function of an object.
528  * This overload passes just the buffer index to the method, no parameters.
529  */
530 template< typename T >
531 class MessageDoubleBuffered0 : public MessageBase
532 {
533 public:
534
535   typedef void(T::*MemberFunction)( BufferIndex );
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    */
544   MessageDoubleBuffered0( const T* obj, MemberFunction member )
545   : MessageBase(),
546     object( const_cast< T* >( obj ) ),
547     memberFunction( member )
548   {
549   }
550
551   /**
552    * Virtual destructor
553    */
554   virtual ~MessageDoubleBuffered0()
555   {
556   }
557
558   /**
559    * @copydoc MessageBase::Process
560    */
561   virtual void Process( BufferIndex bufferIndex )
562   {
563     DALI_ASSERT_DEBUG( object && "Message does not have an object" );
564     (object->*memberFunction)( bufferIndex );
565   }
566
567 private:
568
569   T* object;
570   MemberFunction memberFunction;
571
572 };
573
574
575 /**
576  * Templated message which calls a member function of an object.
577  * This overload passes a value-type to set a double-buffered property.
578  * Template parameters need to match the MemberFunction!
579  * The message will contain copy of the value (in case of & or const&)
580  */
581 template< typename T, typename P >
582 class MessageDoubleBuffered1 : public MessageBase
583 {
584 public:
585
586   typedef void(T::*MemberFunction)(
587       BufferIndex,
588       typename ParameterType< P >::PassingType );
589
590   /**
591    * Create a message.
592    * @note The object is expected to be const in the thread which sends this message.
593    * However it can be modified when Process() is called in a different thread.
594    * @param[in] obj The object.
595    * @param[in] member The member function of the object.
596    * @param[in] p The second parameter to pass.
597    */
598   MessageDoubleBuffered1( const T* obj,
599                           MemberFunction member,
600                           typename ParameterType< P >::PassingType p )
601   : MessageBase(),
602     object( const_cast< T* >( obj ) ),
603     memberFunction( member ),
604     param( p )
605   {
606   }
607
608   /**
609    * Virtual destructor
610    */
611   virtual ~MessageDoubleBuffered1()
612   {
613   }
614
615   /**
616    * @copydoc MessageBase::Process
617    */
618   virtual void Process( BufferIndex bufferIndex )
619   {
620     DALI_ASSERT_DEBUG( object && "Message does not have an object" );
621     (object->*memberFunction)( bufferIndex,  param );
622   }
623
624 private:
625
626   T* object;
627   MemberFunction memberFunction;
628   typename ParameterType< P >::HolderType param;
629
630 };
631
632 /**
633  * Templated message which calls a member function of an object.
634  * This overload passes two value-types to set double-buffered properties.
635  * Template parameters need to match the MemberFunction!
636  * The message will contain copy of the value (in case of & or const&)
637  */
638 template< typename T, typename P2, typename P3 >
639 class MessageDoubleBuffered2 : public MessageBase
640 {
641 public:
642
643   typedef void(T::*MemberFunction)(
644       BufferIndex,
645       typename ParameterType< P2 >::PassingType,
646       typename ParameterType< P3 >::PassingType );
647
648   /**
649    * Create a message.
650    * @note The object is expected to be const in the thread which sends this message.
651    * However it can be modified when Process() is called in a different thread.
652    * @param[in] obj The object.
653    * @param[in] member The member function of the object.
654    * @param[in] p2 The second parameter to pass to the function.
655    * @param[in] p3 The third parameter to pass to the function.
656    */
657   MessageDoubleBuffered2( const T* obj,
658                           MemberFunction member,
659                           typename ParameterType< P2 >::PassingType p2,
660                           typename ParameterType< P3 >::PassingType p3 )
661   : MessageBase(),
662     object( const_cast< T* >( obj ) ),
663     memberFunction( member ),
664     param2( p2 ),
665     param3( p3 )
666   {
667   }
668
669   /**
670    * Virtual destructor
671    */
672   virtual ~MessageDoubleBuffered2()
673   {
674   }
675
676   /**
677    * @copydoc MessageBase::Process
678    */
679   virtual void Process( BufferIndex bufferIndex )
680   {
681     DALI_ASSERT_DEBUG( object && "Message does not have an object" );
682     (object->*memberFunction)(
683         bufferIndex, param2, param3 );
684   }
685
686 private:
687
688   T* object;
689   MemberFunction memberFunction;
690   typename ParameterType< P2 >::HolderType param2;
691   typename ParameterType< P3 >::HolderType param3;
692
693 };
694
695
696 /**
697  * Templated message which calls a member function of an object.
698  * This overload passes three value-types to set double-buffered properties.
699  * Template parameters need to match the MemberFunction!
700  * The message will contain copy of the value (in case of & or const&)
701  */
702 template< typename T, typename P2, typename P3, typename P4 >
703 class MessageDoubleBuffered3 : public MessageBase
704 {
705 public:
706
707   typedef void(T::*MemberFunction)(
708       BufferIndex,
709       typename ParameterType< P2 >::PassingType,
710       typename ParameterType< P3 >::PassingType,
711       typename ParameterType< P4 >::PassingType );
712
713   /**
714    * Create a message.
715    * @note The object is expected to be const in the thread which sends this message.
716    * However it can be modified when Process() is called in a different thread.
717    * @param[in] obj The object.
718    * @param[in] member The member function of the object.
719    * @param[in] p2 The second parameter to pass.
720    * @param[in] p3 The third parameter to pass.
721    * @param[in] p4 The forth parameter to pass.
722    */
723   MessageDoubleBuffered3( const T* obj,
724                           MemberFunction member,
725                           typename ParameterType< P2 >::PassingType p2,
726                           typename ParameterType< P3 >::PassingType p3,
727                           typename ParameterType< P4 >::PassingType p4 )
728   : MessageBase(),
729     object( const_cast< T* >( obj ) ),
730     memberFunction( member ),
731     param2( p2 ),
732     param3( p3 ),
733     param4( p4 )
734   {
735   }
736
737   /**
738    * Virtual destructor
739    */
740   virtual ~MessageDoubleBuffered3()
741   {
742   }
743
744   /**
745    * @copydoc MessageBase::Process
746    */
747   virtual void Process( BufferIndex bufferIndex )
748   {
749     DALI_ASSERT_DEBUG( object && "Message does not have an object" );
750     (object->*memberFunction)( bufferIndex, param2, param3, param4 );
751   }
752
753 private:
754
755   T* object;
756   MemberFunction memberFunction;
757   typename ParameterType< P2 >::HolderType param2;
758   typename ParameterType< P3 >::HolderType param3;
759   typename ParameterType< P4 >::HolderType param4;
760
761 };
762
763 /**
764  * Templated message which calls a member function of an object.
765  * This overload passes four value-types to set double-buffered properties.
766  * Template parameters need to match the MemberFunction!
767  * The message will contain copy of the value (in case of & or const&)
768  */
769 template< typename T, typename P2, typename P3, typename P4, typename P5 >
770 class MessageDoubleBuffered4 : public MessageBase
771 {
772 public:
773
774   typedef void(T::*MemberFunction)(
775       BufferIndex,
776       typename ParameterType< P2 >::PassingType,
777       typename ParameterType< P3 >::PassingType,
778       typename ParameterType< P4 >::PassingType,
779       typename ParameterType< P5 >::PassingType );
780
781   /**
782    * Create a message.
783    * @note The object is expected to be const in the thread which sends this message.
784    * However it can be modified when Process() is called in a different thread.
785    * @param[in] obj The object.
786    * @param[in] member The member function of the object.
787    * @param[in] p2 The second parameter to pass.
788    * @param[in] p3 The third parameter to pass.
789    * @param[in] p4 The forth parameter to pass.
790    * @param[in] p5 The fifth parameter to pass.
791    */
792   MessageDoubleBuffered4( const T* obj,
793                           MemberFunction member,
794                           typename ParameterType< P2 >::PassingType p2,
795                           typename ParameterType< P3 >::PassingType p3,
796                           typename ParameterType< P4 >::PassingType p4,
797                           typename ParameterType< P5 >::PassingType p5 )
798   : MessageBase(),
799     object( const_cast< T* >( obj ) ),
800     memberFunction( member ),
801     param2( p2 ),
802     param3( p3 ),
803     param4( p4 ),
804     param5( p5 )
805   {
806   }
807
808   /**
809    * Virtual destructor
810    */
811   virtual ~MessageDoubleBuffered4()
812   {
813   }
814
815   /**
816    * @copydoc MessageBase::Process
817    */
818   virtual void Process( BufferIndex bufferIndex )
819   {
820     DALI_ASSERT_DEBUG( object && "Message does not have an object" );
821     (object->*memberFunction)( bufferIndex, param2, param3, param4, param5 );
822   }
823
824 private:
825
826   T* object;
827   MemberFunction memberFunction;
828   typename ParameterType< P2 >::HolderType param2;
829   typename ParameterType< P3 >::HolderType param3;
830   typename ParameterType< P4 >::HolderType param4;
831   typename ParameterType< P5 >::HolderType param5;
832
833 };
834
835 } // namespace Internal
836
837 } // namespace Dali
838
839 #endif // __DALI_INTERNAL_MESSAGE_H__