neoGFX
Cross-platform C++ app/game engine
i_plugin_event.hpp
Go to the documentation of this file.
1 // i_plugin_event.hpp
2 /*
3  * Copyright (c) 2015, 2020 Leigh Johnston.
4  *
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are
9  * met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  *
14  * * Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in the
16  * documentation and/or other materials provided with the distribution.
17  *
18  * * Neither the name of Leigh Johnston nor the names of any
19  * other contributors to this software may be used to endorse or
20  * promote products derived from this software without specific prior
21  * written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
24  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
25  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
27  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 #pragma once
37 
38 #include <neolib/neolib.hpp>
39 #include <memory>
41 #include <neolib/task/event.hpp>
42 
43 namespace neolib
44 {
45  namespace plugin_events
46  {
47  using neolib::sink;
48 
49  template <typename... Arguments>
51  {
52  typedef i_event_callback<Arguments...> self_type;
53  public:
55  public:
56  virtual ~i_event_callback() = default;
57  public:
58  ref_ptr<i_event_callback<Arguments...>> clone() const
59  {
60  return ref_ptr<i_event_callback<Arguments...>>{ do_clone() };
61  }
62  public:
63  virtual void operator()(Arguments... aArguments) const = 0;
64  private:
65  virtual i_event_callback<Arguments...>* do_clone() const = 0;
66  };
67 
68  template <typename... Arguments>
69  class event_callback : public reference_counted<i_event_callback<Arguments...>>, public std::function<void(Arguments...)>
70  {
71  typedef std::function<void(Arguments...)> base_type;
72  public:
73  using base_type::base_type;
74  public:
75  void operator()(Arguments... aArguments) const override
76  {
77  base_type::operator()(aArguments...);
78  }
79  private:
80  i_event_callback<Arguments...>* do_clone() const override
81  {
82  return new event_callback{ *this };
83  }
84  };
85 
86  template <typename... Arguments>
87  class i_event
88  {
89  public:
90  typedef i_event_callback<Arguments...> abstract_callback;
91  typedef event_callback<Arguments...> callback;
92  public:
93  virtual ~i_event() = default;
94  public:
95  virtual const neolib::i_event& raw_event() const = 0;
96  virtual neolib::i_event& raw_event() = 0;
97  public:
98  virtual void pre_trigger() const = 0;
99  public:
100  virtual bool trigger(Arguments... aArguments) const = 0;
101  virtual bool sync_trigger(Arguments... aArguments) const = 0;
102  virtual void async_trigger(Arguments... aArguments) const = 0;
103  virtual bool accepted() const = 0;
104  virtual void accept() const = 0;
105  virtual void ignore() const = 0;
106  public:
107  event_handle subscribe(const callback& aCallback, const void* aUniqueId = nullptr) const
108  {
109  return event_handle{ do_subscribe(aCallback, aUniqueId) };
110  }
111  event_handle operator()(const callback& aCallback, const void* aUniqueId = nullptr) const
112  {
113  return event_handle{ do_subscribe(aCallback, aUniqueId) };
114  }
115  template <typename T>
116  event_handle subscribe(const callback& aCallback, const T* aUniqueIdObject) const
117  {
118  return event_handle{ do_subscribe(aCallback, static_cast<const void*>(aUniqueIdObject)) };
119  }
120  template <typename T>
121  event_handle operator()(const callback& aCallback, const T* aUniqueIdObject) const
122  {
123  return event_handle{ do_subscribe(aCallback, static_cast<const void*>(aUniqueIdObject)) };
124  }
125  template <typename T>
126  event_handle subscribe(const callback& aCallback, const T& aUniqueIdObject) const
127  {
128  return event_handle{ do_subscribe(aCallback, static_cast<const void*>(&aUniqueIdObject)) };
129  }
130  template <typename T>
131  event_handle operator()(const callback& aCallback, const T& aUniqueIdObject) const
132  {
133  return event_handle{ do_subscribe(aCallback, static_cast<const void*>(&aUniqueIdObject)) };
134  }
135  void unsubscribe(event_handle aHandle) const
136  {
137  return do_unsubscribe(aHandle);
138  }
139  void unsubscribe(const void* aUniqueId) const
140  {
141  return do_unsubscribe(aUniqueId);
142  }
143  template <typename T>
144  void unsubscribe(const T* aUniqueIdObject) const
145  {
146  return do_unsubscribe(static_cast<const void*>(aUniqueIdObject));
147  }
148  template <typename T>
149  void unsubscribe(const T& aUniqueIdObject) const
150  {
151  return do_unsubscribe(static_cast<const void*>(&aUniqueIdObject));
152  }
153  private:
154  virtual event_handle do_subscribe(const abstract_callback& aCallback, const void* aUniqueId = nullptr) const = 0;
155  virtual void do_unsubscribe(event_handle aHandle) const = 0;
156  virtual void do_unsubscribe(const void* aUniqueId) const = 0;
157  };
158 
159  #define detail_event_subscribe( declName, ... ) \
160  neolib::event_handle declName(const neolib::plugin_events::event_callback<__VA_ARGS__>& aCallback, const void* aUniqueId = nullptr) const { return declName()(aCallback, aUniqueId); }\
161  neolib::event_handle declName(const neolib::plugin_events::event_callback<__VA_ARGS__>& aCallback, const void* aUniqueId = nullptr) { return declName()(aCallback, aUniqueId); }\
162  template <typename T>\
163  neolib::event_handle declName(const neolib::plugin_events::event_callback<__VA_ARGS__>& aCallback, const T* aUniqueObject) const { return declName()(aCallback, static_cast<const void*>(aUniqueObject)); }\
164  template <typename T>\
165  neolib::event_handle declName(const neolib::plugin_events::event_callback<__VA_ARGS__>& aCallback, const T* aUniqueObject) { return declName()(aCallback, static_cast<const void*>(aUniqueObject)); }\
166  template <typename T>\
167  neolib::event_handle declName(const neolib::plugin_events::event_callback<__VA_ARGS__>& aCallback, T&& aUniqueObject) const { return declName()(aCallback, static_cast<const void*>(&aUniqueObject)); }\
168  template <typename T>\
169  neolib::event_handle declName(const neolib::plugin_events::event_callback<__VA_ARGS__>& aCallback, T&& aUniqueObject) { return declName()(aCallback, static_cast<const void*>(&aUniqueObject)); }
170 
171  #define declare_event( declName, ... ) \
172  virtual const neolib::plugin_events::i_event<__VA_ARGS__>& ev_##declName() const = 0;\
173  virtual neolib::plugin_events::i_event<__VA_ARGS__>& ev_##declName() = 0;\
174  const neolib::plugin_events::i_event<__VA_ARGS__>& declName() const { return ev_##declName(); }\
175  neolib::plugin_events::i_event<__VA_ARGS__>& declName() { return ev_##declName(); }\
176  detail_event_subscribe(declName, __VA_ARGS__)
177 
178  template <typename... Arguments>
179  class event;
180 
181  #define define_declared_event( name, declName, ... ) \
182  neolib::plugin_events::event<__VA_ARGS__> name; \
183  const neolib::plugin_events::i_event<__VA_ARGS__>& ev_##declName() const override { return name; };\
184  neolib::plugin_events::i_event<__VA_ARGS__>& ev_##declName() override { return name; };
185 
186  #define define_event( name, declName, ... ) \
187  neolib::plugin_events::event<__VA_ARGS__> name; \
188  const neolib::plugin_events::i_event<__VA_ARGS__>& ev_##declName() const { return name; };\
189  neolib::plugin_events::i_event<__VA_ARGS__>& ev_##declName() { return name; };\
190  const neolib::plugin_events::i_event<__VA_ARGS__>& declName() const { return ev_##declName(); }\
191  neolib::plugin_events::i_event<__VA_ARGS__>& declName() { return ev_##declName(); }\
192  detail_event_subscribe(declName, __VA_ARGS__)
193  }
194 }
neolib::plugin_events::i_event::unsubscribe
void unsubscribe(const T &aUniqueIdObject) const
Definition: i_plugin_event.hpp:149
neolib::plugin_events::i_event::abstract_callback
i_event_callback< Arguments... > abstract_callback
Definition: i_plugin_event.hpp:90
neolib::plugin_events::event_callback::operator()
void operator()(Arguments... aArguments) const override
Definition: i_plugin_event.hpp:75
neolib::event_handle
Definition: event.hpp:57
neolib::reference_counted
Definition: reference_counted.hpp:94
neolib::sink
class NEOLIB_EXPORT sink
Definition: event.hpp:54
event.hpp
neolib::plugin_events::i_event::raw_event
virtual neolib::i_event & raw_event()=0
reference_counted.hpp
neolib::plugin_events::i_event_callback::operator()
virtual void operator()(Arguments... aArguments) const =0
neolib::i_reference_counted
Definition: i_reference_counted.hpp:58
neolib::plugin_events::i_event_callback
Definition: i_plugin_event.hpp:51
neolib::plugin_events::i_event::pre_trigger
virtual void pre_trigger() const =0
neolib::plugin_events::i_event_callback::abstract_type
self_type abstract_type
Definition: i_plugin_event.hpp:54
neolib::plugin_events::i_event_callback::~i_event_callback
virtual ~i_event_callback()=default
neolib::plugin_events::i_event::sync_trigger
virtual bool sync_trigger(Arguments... aArguments) const =0
neolib::plugin_events::i_event::async_trigger
virtual void async_trigger(Arguments... aArguments) const =0
neolib::plugin_events::i_event
Definition: i_plugin_event.hpp:88
neolib::plugin_events::i_event_callback::clone
ref_ptr< i_event_callback< Arguments... > > clone() const
Definition: i_plugin_event.hpp:58
neolib::plugin_events::i_event::subscribe
event_handle subscribe(const callback &aCallback, const T *aUniqueIdObject) const
Definition: i_plugin_event.hpp:116
neolib::plugin_events::i_event::unsubscribe
void unsubscribe(const void *aUniqueId) const
Definition: i_plugin_event.hpp:139
neolib::plugin_events::i_event::~i_event
virtual ~i_event()=default
neolib::plugin_events::i_event::accept
virtual void accept() const =0
neolib
Definition: application.hpp:46
neolib::plugin_events::i_event::accepted
virtual bool accepted() const =0
neolib::plugin_events::i_event::subscribe
event_handle subscribe(const callback &aCallback, const void *aUniqueId=nullptr) const
Definition: i_plugin_event.hpp:107
neolib::plugin_events::i_event::callback
event_callback< Arguments... > callback
Definition: i_plugin_event.hpp:91
neolib::plugin_events::i_event::unsubscribe
void unsubscribe(const T *aUniqueIdObject) const
Definition: i_plugin_event.hpp:144
neolib::plugin_events::i_event::raw_event
virtual const neolib::i_event & raw_event() const =0
neolib::plugin_events::i_event::operator()
event_handle operator()(const callback &aCallback, const T &aUniqueIdObject) const
Definition: i_plugin_event.hpp:131
neolib::plugin_events::i_event::unsubscribe
void unsubscribe(event_handle aHandle) const
Definition: i_plugin_event.hpp:135
neolib::plugin_events::i_event::ignore
virtual void ignore() const =0
neolib::plugin_events::event_callback
Definition: i_plugin_event.hpp:70
neolib::plugin_events::i_event::operator()
event_handle operator()(const callback &aCallback, const T *aUniqueIdObject) const
Definition: i_plugin_event.hpp:121
neolib::i_event
Definition: i_event.hpp:71
neolib::plugin_events::i_event::operator()
event_handle operator()(const callback &aCallback, const void *aUniqueId=nullptr) const
Definition: i_plugin_event.hpp:111
neolib::ref_ptr
Definition: reference_counted.hpp:181
neolib.hpp
neolib::plugin_events::i_event::subscribe
event_handle subscribe(const callback &aCallback, const T &aUniqueIdObject) const
Definition: i_plugin_event.hpp:126
neolib::plugin_events::i_event::trigger
virtual bool trigger(Arguments... aArguments) const =0