NAP
servicerunner.h
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4 
5 #pragma once
6 
7 // Local Includes
8 #include "app.h"
9 #include "appeventhandler.h"
10 
11 // External Includes
12 #include <rtti/typeinfo.h>
13 #include <nap/core.h>
14 #include <nap/datetime.h>
15 #include <thread>
16 
17 namespace nap
18 {
34  template<typename APP, typename HANDLER>
36  {
37  RTTI_ENABLE()
38  public:
43  ServiceRunner(nap::Core& core);
44 
48  virtual ~ServiceRunner();
49 
53  ServiceRunner(ServiceRunner&) = delete;
54  ServiceRunner& operator=(const ServiceRunner&) = delete;
55 
59  ServiceRunner(ServiceRunner&&) = delete;
61 
67  bool init(utility::ErrorState& error);
68 
73  void update();
74 
79  int shutdown();
80 
85  int exitCode() const { return mExitCode; }
86 
90  APP& getApp();
91 
95  Core& getCore() { return mCore; }
96 
100  const Core& getCore() const { return mCore; }
101 
105  HANDLER& getHandler();
106 
107  private:
108  nap::Core& mCore; // Core
109  std::unique_ptr<APP> mApp = nullptr; // App this runner works with
110  std::unique_ptr<HANDLER> mHandler = nullptr; // App handler this runner works with
111  std::function<void(double)> mUpdateCall; // Callback to the application update call
112  int mExitCode = 0; // Application exit code, available after shutdown
113  Core::ServicesHandle mServicesHandle = nullptr; // Handle to initialized and running services
114  };
115 
116 
118  // Template definitions
120 
121  template<typename APP, typename HANDLER>
123  {
124  return *mApp;
125  }
126 
127 
128  template<typename APP, typename HANDLER>
130  {
131  return *mHandler;
132  }
133 
134 
135  template<typename APP, typename HANDLER>
137  {
138  // Ensure the app is an application
139  assert(RTTI_OF(APP).is_derived_from(RTTI_OF(BaseApp)));
140 
141  // Ensure the handler is an app event handler
142  assert(RTTI_OF(HANDLER).is_derived_from(RTTI_OF(AppEventHandler)));
143 
144  // Create 'm
145  mApp = std::make_unique<APP>(core);
146  mHandler = std::make_unique<HANDLER>(*mApp);
147  }
148 
149 
150  template<typename APP, typename HANDLER>
152  {
153  nap::BaseApp& app = getApp();
154  nap::AppEventHandler& app_event_handler = getHandler();
155 
156  // Initialize engine
157  if (!mCore.initializeEngine(error))
158  {
159  error.fail("Unable to initialize engine");
160  return false;
161  }
162 
163  // Initialize the various services
164  // Bail if handle is invalid, this means service initialization failed
165  mServicesHandle = mCore.initializeServices(error);
166  if (mServicesHandle == nullptr)
167  return false;
168 
169 #ifdef NAP_ENABLE_PYTHON
170  if (!mCore.initializePython(error))
171  return false;
172 #endif
173 
174  // Initialize application
175  if(!error.check(app.init(error), "Unable to initialize application"))
176  return false;
177 
178  // Start event handler
179  app_event_handler.start();
180 
181  // Pointer to function used inside update call by core
182  mUpdateCall = std::bind(&APP::update, mApp.get(), std::placeholders::_1);
183 
184  // Start core
185  mCore.start();
186 
187  // Message successful start
188  return true;
189  }
190 
191 
192  template<typename APP, typename HANDLER>
194  {
195  // Process app specific messages
196  nap::AppEventHandler& app_event_handler = getHandler();
197  app_event_handler.process();
198 
199  // update
200  mCore.update(mUpdateCall);
201  }
202 
203 
204  template<typename APP, typename HANDLER>
206  {
207  // Stop handling events
208  nap::AppEventHandler& app_event_handler = getHandler();
209  app_event_handler.shutdown();
210 
211  // Shutdown
212  nap::BaseApp& app = getApp();
213  mExitCode = app.shutdown();
214 
215  // Shut down services
216  mServicesHandle.reset(nullptr);
217 
218  // Shutdown core
219  return mExitCode;
220  }
221 
222 
223  template<typename APP, typename HANDLER>
225  {
226  // First clear the handler as it points to our app
227  mHandler.reset();
228 
229  // Now clear the app
230  mApp.reset();
231  }
232 }
nap::ServiceRunner::getHandler
HANDLER & getHandler()
Definition: servicerunner.h:129
nap::AppEventHandler::start
virtual void start()
Definition: appeventhandler.h:48
nap::ServiceRunner
Definition: servicerunner.h:35
nap::ServiceRunner::ServiceRunner
ServiceRunner(nap::Core &core)
Definition: servicerunner.h:136
nap::AppEventHandler::process
virtual void process()
Definition: appeventhandler.h:56
nap::ServiceRunner::shutdown
int shutdown()
Definition: servicerunner.h:205
nap::ServiceRunner::getApp
APP & getApp()
Definition: servicerunner.h:122
nap::utility::ErrorState
Definition: errorstate.h:19
nap::AppEventHandler
Definition: appeventhandler.h:19
nap::ServiceRunner::getCore
const Core & getCore() const
Definition: servicerunner.h:100
nap::ServiceRunner::update
void update()
Definition: servicerunner.h:193
nap::Core
Definition: core.h:82
nap::BaseApp::init
virtual bool init(utility::ErrorState &error)
Definition: app.h:51
nap::BaseApp::shutdown
virtual int shutdown()
Definition: app.h:80
nap::ServiceRunner::exitCode
int exitCode() const
Definition: servicerunner.h:85
nap
Definition: templateapp.h:17
nap::AppEventHandler::shutdown
virtual void shutdown()
Definition: appeventhandler.h:61
nap::ServiceRunner::operator=
ServiceRunner & operator=(const ServiceRunner &)=delete
nap::ServiceRunner::~ServiceRunner
virtual ~ServiceRunner()
Definition: servicerunner.h:224
nap::ServiceRunner::getCore
Core & getCore()
Definition: servicerunner.h:95
nap::Core::ServicesHandle
std::unique_ptr< Services > ServicesHandle
Definition: core.h:89
nap::ServiceRunner::init
bool init(utility::ErrorState &error)
Definition: servicerunner.h:151
nap::BaseApp
Definition: app.h:22