Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #pragma once
00025 #ifndef ATSCPPAPI_ASYNC_H_
00026 #define ATSCPPAPI_ASYNC_H_
00027 #include <list>
00028 #include <atscppapi/Mutex.h>
00029 #include <atscppapi/noncopyable.h>
00030 #include <atscppapi/shared_ptr.h>
00031
00032 namespace atscppapi {
00033
00034
00035
00036
00037
00038
00039
00040
00041 class AsyncDispatchControllerBase : noncopyable {
00042 public:
00043
00044
00045
00046
00047
00048 virtual bool dispatch() = 0;
00049
00050
00051 virtual void disable() = 0;
00052
00053
00054 virtual bool isEnabled() = 0;
00055
00056 virtual ~AsyncDispatchControllerBase() { }
00057 };
00058
00059
00060
00061
00062
00063
00064
00065
00066 class AsyncProvider {
00067 public:
00068
00069
00070
00071
00072
00073 virtual void run() = 0;
00074
00075
00076
00077 virtual void cancel() {
00078 if (dispatch_controller_) {
00079 dispatch_controller_->disable();
00080 }
00081 }
00082
00083 virtual ~AsyncProvider() { }
00084
00085 protected:
00086 shared_ptr<AsyncDispatchControllerBase> getDispatchController() { return dispatch_controller_; }
00087
00088 private:
00089 shared_ptr<AsyncDispatchControllerBase> dispatch_controller_;
00090 void doRun(shared_ptr<AsyncDispatchControllerBase> dispatch_controller) {
00091 dispatch_controller_ = dispatch_controller;
00092 run();
00093 }
00094 friend class Async;
00095 };
00096
00097
00098
00099
00100
00101
00102
00103 template<typename AsyncEventReceiverType, typename AsyncProviderType>
00104 class AsyncDispatchController : public AsyncDispatchControllerBase {
00105 public:
00106 bool dispatch() {
00107 bool ret = false;
00108 ScopedSharedMutexLock scopedLock(dispatch_mutex_);
00109 if (event_receiver_) {
00110 event_receiver_->handleAsyncComplete(static_cast<AsyncProviderType &>(*provider_));
00111 ret = true;
00112 }
00113 return ret;
00114 }
00115
00116 void disable() {
00117 ScopedSharedMutexLock scopedLock(dispatch_mutex_);
00118 event_receiver_ = NULL;
00119 }
00120
00121 bool isEnabled() {
00122 return (event_receiver_ != NULL);
00123 }
00124
00125
00126
00127
00128
00129
00130
00131
00132 AsyncDispatchController(AsyncEventReceiverType *event_receiver, AsyncProviderType *provider, shared_ptr<Mutex> mutex) :
00133 event_receiver_(event_receiver), dispatch_mutex_(mutex), provider_(provider) {
00134 }
00135
00136 virtual ~AsyncDispatchController() { }
00137 public:
00138 AsyncEventReceiverType *event_receiver_;
00139 shared_ptr<Mutex> dispatch_mutex_;
00140 private:
00141 AsyncProviderType *provider_;
00142 };
00143
00144
00145
00146
00147
00148
00149
00150
00151 template<typename AsyncEventReceiverType, typename AsyncProviderType>
00152 class AsyncReceiverPromise : noncopyable {
00153 public:
00154 AsyncReceiverPromise(shared_ptr<AsyncDispatchController<AsyncEventReceiverType, AsyncProviderType> > dispatch_controller) :
00155 dispatch_controller_(dispatch_controller) { }
00156
00157 ~AsyncReceiverPromise() {
00158 ScopedSharedMutexLock scopedLock(dispatch_controller_->dispatch_mutex_);
00159 dispatch_controller_->event_receiver_ = NULL;
00160 }
00161 protected:
00162 shared_ptr<AsyncDispatchController<AsyncEventReceiverType, AsyncProviderType> > dispatch_controller_;
00163 };
00164
00165
00166
00167
00168
00169 template<typename AsyncProviderType>
00170 class AsyncReceiver : noncopyable {
00171 public:
00172
00173
00174
00175
00176
00177
00178
00179 virtual void handleAsyncComplete(AsyncProviderType &provider) = 0;
00180 virtual ~AsyncReceiver() { }
00181 protected:
00182 AsyncReceiver() { }
00183 friend class Async;
00184 private:
00185 mutable std::list<shared_ptr<AsyncReceiverPromise<AsyncReceiver<AsyncProviderType>, AsyncProviderType> > > receiver_promises_;
00186 };
00187
00188
00189
00190
00191 class Async : noncopyable {
00192 public:
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204 template<typename AsyncProviderType>
00205 static void execute(AsyncReceiver<AsyncProviderType> *event_receiver, AsyncProviderType *provider, shared_ptr<Mutex> mutex) {
00206 if (!mutex.get()) {
00207 mutex.reset(new Mutex(Mutex::TYPE_RECURSIVE));
00208 }
00209 shared_ptr<AsyncDispatchController<AsyncReceiver<AsyncProviderType>, AsyncProviderType > > dispatcher(
00210 new AsyncDispatchController<AsyncReceiver<AsyncProviderType>, AsyncProviderType >(event_receiver, provider, mutex));
00211 shared_ptr<AsyncReceiverPromise<AsyncReceiver<AsyncProviderType>, AsyncProviderType > > receiver_promise(
00212 new AsyncReceiverPromise<AsyncReceiver<AsyncProviderType>, AsyncProviderType >(dispatcher));
00213 event_receiver->receiver_promises_.push_back(receiver_promise);
00214 provider->doRun(dispatcher);
00215 }
00216 };
00217
00218 }
00219
00220
00221 #endif