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