Scope
BaseController_p.h
1 #pragma once
2 
3 #include "parameters/Scope.h"
4 #include "ScopeDatatypes.h"
5 #include "helpers/ScopeException.h"
6 
7 namespace scope {
8 
10 template<uint32_t N_ACTIVES, bool STATIC_PIMPL>
11 class BaseController<N_ACTIVES, STATIC_PIMPL>::Impl {
12 
13 protected:
15  std::array<std::shared_future<ControllerReturnStatus>, N_ACTIVES> futures;
16 
18  std::array<StopCondition, N_ACTIVES> stops;
19 
22 
23 private:
25  Impl(const Impl& i);
26 
28  Impl operator=(const Impl& i);
29 
30 protected:
34  virtual ControllerReturnStatus Run(StopCondition* const ac, const uint32_t& _n) {
35  DBOUT(L"BaseControllerImpl::Run - this should not happen, the derived class' Run method should have been called\n");
36  while ( !ac->IsSet() )
37  std::this_thread::sleep_for(std::chrono::milliseconds(100));
38  ac->Set(false);
39  return ControllerReturnStatus(ControllerReturnStatus::error); // If this ever gets executed, something went wrong...
40  }
41 
42 public:
44  Impl(const parameters::Scope& _parameters)
45  : parameters(_parameters) {
46  }
47 
50  virtual ~Impl() {
51  DBOUT(L"BaseController::Impl::~Impl\n");
52  }
53 
56  virtual void Start(const parameters::Scope& _params) {
57  DBOUT(L"BaseController::Impl::Start\n");
58  parameters = _params;
59  for( uint32_t a = 0; a < N_ACTIVES ; a++ ) {
60  stops[a].Set(false);
61  // Let "Run" run asynchronously and get its future
62  futures[a] = std::async(std::bind(&Impl::Run, this, &stops[a], a));
63  }
64  }
65 
68  virtual void StopOne(const uint32_t& _a) {
69  ATLASSERT(_a < N_ACTIVES);
70  stops[_a].Set(true);
71  }
72 
74  virtual void StopAll() {
75  DBOUT(L"BaseController::Impl::Stop\n");
76  for ( uint32_t a = 0 ; a < N_ACTIVES ; a++ )
77  StopOne(a);
78  }
79 
84  virtual ControllerReturnStatus WaitForOne(const uint32_t& _a, const int32_t& _wait_time) {
85  if ( futures[_a].valid() ) {
86  std::future_status::future_status state(std::future_status::ready);
87 
88  // Wait (either indefinitely or _wait_time
89  if ( _wait_time == -1 )
90  futures[_a].wait();
91  else
92  state = futures[_a].wait_for(std::chrono::milliseconds(_wait_time));
93 
94  // If async returned, get the future's value here
95  if ( state == std::future_status::ready )
96  return futures[_a].get();
97  // Landing here means, wait_for ran into a timeout
98  else
99  throw ScopeException("WaitForOne did not succeed, async thread did not return");
100  }
101  else
102  DBOUT(L"WaitForOne future is not valid (async worker function is not running)");
103 
104  return ControllerReturnStatus::error;
105  }
106 
110  virtual ControllerReturnStatus WaitForAll(const int32_t& _wait_time) {
111  ControllerReturnStatus totalresult(ControllerReturnStatus::none);
112  for ( uint32_t a = 0 ; a < N_ACTIVES ; a++ ) {
113  try {
114  totalresult = (ControllerReturnStatus)( totalresult | WaitForOne(a, _wait_time) );
115  }
116  catch (... ) { ScopeExceptionHandler(__FUNCTION__, true, true); }
117  }
118  DBOUT(L"BaseController::Impl::WaitForAll returns\n");
119  return totalresult;
120  }
121 };
122 
123 }
virtual ControllerReturnStatus Run(StopCondition *const ac, const uint32_t &_n)
The worker function that will run asynchronously.
parameters::Scope parameters
the Controller's own set of ScopeParameters
Thread-safe lock-free bool to signal a requested stop to the worker function currently executed in th...
Definition: helpers.h:87
The master parameters class.
Definition: Scope.h:204
Simple exception class for Scope.
Definition: ScopeException.h:9
virtual ~Impl()
It is important that this is virtual, only by this the correct destructor for the pimpl is called in ...
std::array< StopCondition, N_ACTIVES > stops
handed to the asynchronous Run worker functions
std::array< std::shared_future< ControllerReturnStatus >, N_ACTIVES > futures
futures from the asynchronous Run worker functions
virtual void Start(const parameters::Scope &_params)
Execute the Run worker functions asynchronously, give them a reference to a StopCondition and get the...
In here all declarations for all kinds of datatypes Scope needs.
virtual ControllerReturnStatus WaitForAll(const int32_t &_wait_time)
Wait for the futures of all async worker functions.
virtual void StopAll()
Request all async worker function to stop.
virtual void StopOne(const uint32_t &_a)
Request one async worker function to stop by settings its StopCondition to true.
#define DBOUT(s)
A debug output to the debug console.
Definition: helpers.h:153
void ScopeExceptionHandler(const std::string &_origin, const bool &_log, const bool &_showmessagebox, const bool &_trace, const bool &_rethrow)
Handles all exceptions and does nice logging.
Impl(const parameters::Scope &_parameters)
virtual ControllerReturnStatus WaitForOne(const uint32_t &_a, const int32_t &_wait_time)
Waits for the future of one async worker function.
void Set(const bool &_a=true)
Definition: helpers.h:108
BaseController operator=(const BaseController &i)
disable assignment
Base class for all controllers.
Implementation class of the BaseController, uses std::async to execute worker functions in a separate...
bool IsSet() const
Definition: helpers.h:105