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