foobar2000 SDK  2015-08-03
main_thread_callback.h
Go to the documentation of this file.
1 #include <functional>
2 
4 class NOVTABLE main_thread_callback : public service_base {
5 public:
7  virtual void callback_run() = 0;
8 
9  void callback_enqueue(); // helper
10 
11  FB2K_MAKE_SERVICE_INTERFACE(main_thread_callback,service_base);
12 };
13 
18 class NOVTABLE main_thread_callback_manager : public service_base {
19 public:
21  virtual void add_callback(service_ptr_t<main_thread_callback> p_callback) = 0;
22 
23  FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(main_thread_callback_manager);
24 };
25 
26 
27 void main_thread_callback_add(main_thread_callback::ptr ptr);
28 
29 template<typename t_class> static void main_thread_callback_spawn() {
31 }
32 template<typename t_class, typename t_param1> static void main_thread_callback_spawn(const t_param1 & p1) {
34 }
35 template<typename t_class, typename t_param1, typename t_param2> static void main_thread_callback_spawn(const t_param1 & p1, const t_param2 & p2) {
37 }
38 
39 // Proxy class - friend this to allow callInMainThread to access your private methods
41 public:
42  template<typename host_t, typename param_t>
43  static void callThis(host_t * host, param_t & param) {
44  host->inMainThread(param);
45  }
46  template<typename host_t>
47  static void callThis( host_t * host ) {
48  host->inMainThread();
49  }
50 };
51 
52 // Internal class, do not use.
53 template<typename service_t, typename param_t>
55 public:
56  _callInMainThreadSvc_t(service_t * host, param_t const & param) : m_host(host), m_param(param) {}
57  void callback_run() {
58  callInMainThread::callThis(m_host.get_ptr(), m_param);
59  }
60 private:
62  param_t m_param;
63 };
64 
65 
66 // Main thread callback helper. You can use this to easily invoke inMainThread(someparam) on your class without writing any wrapper code.
67 // Requires myservice_t to be a fb2k service class with reference counting.
68 template<typename myservice_t, typename param_t>
69 static void callInMainThreadSvc(myservice_t * host, param_t const & param) {
71  service_ptr_t<impl_t> obj = new service_impl_t<impl_t>(host, param);
73 }
74 
75 
76 
77 
85 public:
86 
87  typedef std::function< void () > func_t;
88 
90 
92  public:
93  entryFunc( func_t const & func, killswitch_t ks ) : m_ks(ks), m_func(func) {}
94 
95  void callback_run() {
96  if (!*m_ks) m_func();
97  }
98 
99  private:
100  killswitch_t m_ks;
101  func_t m_func;
102  };
103 
104  template<typename host_t, typename arg_t>
105  class entry : public main_thread_callback {
106  public:
107  entry( host_t * host, arg_t const & arg, killswitch_t ks ) : m_ks(ks), m_host(host), m_arg(arg) {}
108  void callback_run() {
109  if (!*m_ks) callInMainThread::callThis( m_host, m_arg );
110  }
111  private:
112  killswitch_t m_ks;
113  host_t * m_host;
114  arg_t m_arg;
115  };
116  template<typename host_t>
118  public:
119  entryVoid( host_t * host, killswitch_t ks ) : m_ks(ks), m_host(host) {}
120  void callback_run() {
121  if (!*m_ks) callInMainThread::callThis( m_host );
122  }
123  private:
124  killswitch_t m_ks;
125  host_t * m_host;
126  };
127 
128  void add(func_t f) {
129  add_( new service_impl_t< entryFunc > ( f, m_ks ) );
130  }
131 
132  template<typename host_t, typename arg_t>
133  void add( host_t * host, arg_t const & arg) {
134  add_( new service_impl_t< entry<host_t, arg_t> >( host, arg, m_ks ) );
135  }
136  template<typename host_t>
137  void add( host_t * host ) {
138  add_( new service_impl_t< entryVoid<host_t> >( host, m_ks ) );
139  }
140  void add_( main_thread_callback::ptr cb ) {
142  }
143 
145  m_ks.new_t();
146  * m_ks = false;
147  }
148  void shutdown() {
149  PFC_ASSERT( core_api::is_main_thread() );
150  * m_ks = true;
151  }
153  shutdown();
154  }
155 
156 private:
157  killswitch_t m_ks;
158 
159 };
160 
161 // Modern helper
162 namespace fb2k {
163  void inMainThread( std::function<void () > f );
164 }
void add_(main_thread_callback::ptr cb)
Template implementing reference-counting features of service_base. Intended for dynamic instantiation...
Definition: service_impl.h:4
void main_thread_callback_add(main_thread_callback::ptr ptr)
static void callThis(host_t *host, param_t &param)
void add(host_t *host, arg_t const &arg)
pfc::rcptr_t< bool > killswitch_t
entryVoid(host_t *host, killswitch_t ks)
entryFunc(func_t const &func, killswitch_t ks)
void callback_run()
Gets called from main app thread. See main_thread_callback_manager description for more info...
_callInMainThreadSvc_t(service_t *host, param_t const &param)
void inMainThread(std::function< void() > f)
void callback_run()
Gets called from main app thread. See main_thread_callback_manager description for more info...
entry(host_t *host, arg_t const &arg, killswitch_t ks)
Base class for all service classes. Provides interfaces for reference counter and querying for differ...
Definition: service.h:333
void callback_run()
Gets called from main app thread. See main_thread_callback_manager description for more info...
Autopointer class to be used with all services. Manages reference counter calls behind-the-scenes.
Definition: service.h:55
Helper class to call methods of your class (host class) in main thread with convenience. Deals with the otherwise ugly scenario of your class becoming invalid while a method is queued. Have this as a member of your class, then use m_mthelper.add( this, somearg ) ; to defer a call to this->inMainThread(somearg). If your class becomes invalid before inMainThread is executed, the pending callback is discarded. You can optionally call shutdown() to invalidate all pending callbacks early (in a destructor of your class - without waiting for callInMainThreadHelper destructor to do the job. In order to let callInMainThreadHelper access your private methods, declare friend class callInMainThread.
static void callInMainThreadSvc(myservice_t *host, param_t const &param)
bool is_main_thread()
Returns true if calling thread is main app thread, false otherwise.
service_ptr_t< service_t > m_host
void callback_run()
Gets called from main app thread. See main_thread_callback_manager description for more info...
Helper template used to easily access core services. Usage: static_api_ptr_t<myclass> api; api->doso...
Definition: service.h:533
static void main_thread_callback_spawn()
std::function< void() > func_t
static void callThis(host_t *host)
Callback object class for main_thread_callback_manager service.