1 /*
2  Copyright (c) 2008-2020, Benoit AUTHEMAN All rights reserved.
3 
4  Redistribution and use in source and binary forms, with or without
5  modification, are permitted provided that the following conditions are met:
6     * Redistributions of source code must retain the above copyright
7       notice, this list of conditions and the following disclaimer.
8     * Redistributions in binary form must reproduce the above copyright
9       notice, this list of conditions and the following disclaimer in the
10       documentation and/or other materials provided with the distribution.
11     * Neither the name of the author or Destrat.io nor the
12       names of its contributors may be used to endorse or promote products
13       derived from this software without specific prior written permission.
14 
15  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18  DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
19  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26 
27 //-----------------------------------------------------------------------------
28 // This file is a part of the GTpo software library.
29 //
30 // \file	behaviourable.hpp
31 // \author	benoit@destrat.io
32 // \date	2016 02 08
33 //-----------------------------------------------------------------------------
34 
35 #include "./utils.h"
36 
37 namespace gtpo { // ::gtpo
38 
39 /* Virtual Behaviours Management *///------------------------------------------
40 template < class behaviour_t, class static_behaviours_t  >
41 template < class T >
notify_dynamic_behaviours(void (behaviour_t::* method)(T &),T & arg)42 auto    behaviourable< behaviour_t, static_behaviours_t >::notify_dynamic_behaviours( void (behaviour_t::*method)(T&), T& arg ) noexcept -> void
43 {
44     // Note 20160314: See http://stackoverflow.com/questions/1485983/calling-c-class-methods-via-a-function-pointer
45     // For calling pointer on template template parameter template keyword functions.
46     // std::unique_ptr has no overload for .* or ->* operator
47     // (*behaviour) == (*behaviour.get())
48     // Equivalent to: ((*behaviour.get()).*method)(arg)
49     for ( auto& behaviour : _dynamic_behaviours )
50         if ( behaviour )
51             ((*behaviour).*method)(arg);
52 }
53 
54 template < class behaviour_t, class static_behaviours_t  >
55 template < class T, class T2 >
notify_dynamic_behaviours(void (behaviour_t::* method)(T &,T2 &),T & arg,T2 & arg2)56 auto    behaviourable< behaviour_t, static_behaviours_t >::notify_dynamic_behaviours( void (behaviour_t::*method)(T&, T2&), T& arg, T2& arg2 ) noexcept -> void
57 {
58     // Note 20160314: See http://stackoverflow.com/questions/1485983/calling-c-class-methods-via-a-function-pointer
59     // For calling pointer on template template parameter template keyword functions.
60     // std::unique_ptr has no overload for .* or ->* operator
61     // (*behaviour) == (*behaviour.get())
62     // Equivalent to: ((*behaviour.get()).*method)(arg)
63     for ( auto& behaviour : _dynamic_behaviours )
64         if ( behaviour )
65             ((*behaviour).*method)(arg, arg2);
66 }
67 
68 template < class behaviour_t, class static_behaviours_t  >
69 template < class T, class T2, class T3 >
notify_dynamic_behaviours(void (behaviour_t::* method)(T &,T2 &,const T3 &),T & arg,T2 & arg2,const T3 & arg3)70 auto    behaviourable< behaviour_t, static_behaviours_t >::notify_dynamic_behaviours( void (behaviour_t::*method)(T&, T2&, const T3&), T& arg, T2& arg2, const T3& arg3 ) noexcept -> void
71 {
72     // Note 20160314: See http://stackoverflow.com/questions/1485983/calling-c-class-methods-via-a-function-pointer
73     // For calling pointer on template template parameter template keyword functions.
74     // std::unique_ptr has no overload for .* or ->* operator
75     // (*behaviour) == (*behaviour.get())
76     // Equivalent to: ((*behaviour.get()).*method)(arg)
77     for ( auto& behaviour : _dynamic_behaviours )
78         if ( behaviour )
79             ((*behaviour).*method)(arg, arg2, arg3);
80 }
81 
82 template < class behaviour_t, class static_behaviours_t  >
notify_dynamic_behaviours0(void (behaviour_t::* method)())83 auto    behaviourable< behaviour_t, static_behaviours_t >::notify_dynamic_behaviours0( void (behaviour_t::*method)() ) noexcept -> void
84 {
85     for ( auto& behaviour : _dynamic_behaviours )
86         if ( behaviour )
87             ((*behaviour).*method)();
88 }
89 //-----------------------------------------------------------------------------
90 
91 } // ::gtpo
92 
93