00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #define ACEDIA_REDUCED_ANNOUNCE
00031
00032 #include "invoker.hpp"
00033 #include "actor.hpp"
00034
00035 namespace acedia
00036 {
00037 struct DefaultExitProcessor : public details::AnyArrayProcessor
00038 {
00039 virtual bool operator()(const AnyArray &arr)
00040 {
00041 if (arr.match<Exit>())
00042 {
00043 const Exit &e = arr.uncheckedValueAt<Exit>(0);
00044 if (e.reason() != 0)
00045 throw ActorKilledException(exit_reasons::LINK_EXITED);
00046 }
00047 return false;
00048 }
00049
00050 virtual details::ContinuationInvoker *matchingInvoker(const AnyArray &arr)
00051 {
00052 if (arr.match<Exit>())
00053 {
00054 const Exit &e = arr.uncheckedValueAt<Exit>(0);
00055 if (e.reason() != 0)
00056 return new details::ContinuationInvoker(this, &arr);
00057 }
00058 return NULL;
00059 }
00060 };
00061 }
00062
00063 static acedia::DefaultExitProcessor m_d_e_p;
00064
00065 namespace acedia
00066 {
00067 typedef std::list<details::AnyArrayProcessor*>::const_iterator iter;
00068
00069 Invoker::Invoker() { }
00070
00071 Invoker::Invoker(details::AnyArrayProcessor *proc)
00072 {
00073 m_processors.push_back(proc);
00074 }
00075
00076 Invoker::~Invoker()
00077 {
00078 details::AnyArrayProcessor *p;
00079
00080 while (!m_processors.empty())
00081 {
00082 p = m_processors.front();
00083 delete p;
00084 m_processors.pop_front();
00085 }
00086 }
00087
00088 void Invoker::pop_back()
00089 {
00090 if (!m_processors.empty())
00091 {
00092 details::AnyArrayProcessor *aap = m_processors.back();
00093 m_processors.pop_back();
00094 delete aap;
00095 }
00096 }
00097
00098 Invoker &Invoker::add(details::AnyArrayProcessor* proc)
00099 {
00100 m_processors.push_back(proc);
00101 return *this;
00102 }
00103
00104 Invoker &Invoker::prepend(details::AnyArrayProcessor* proc)
00105 {
00106 m_processors.push_front(proc);
00107 return *this;
00108 }
00109
00110 void Invoker::pop_front()
00111 {
00112 if (!m_processors.empty())
00113 {
00114 details::AnyArrayProcessor* aap = m_processors.front();
00115 m_processors.pop_front();
00116 delete aap;
00117 }
00118 }
00119
00120 bool Invoker::operator()(const Message &msg, bool trapExit)
00121 {
00122 m_lcm = msg;
00123
00124 if (!trapExit) { (void) m_d_e_p(m_lcm); }
00125 for (iter i = m_processors.begin(); i != m_processors.end(); ++i)
00126 {
00127 if ((*(*i))(m_lcm)) return true;
00128 }
00129 return false;
00130 }
00131
00132 details::ContinuationInvoker *Invoker::matchingInvokerTo(Message msg, bool trapExit)
00133 {
00134 m_lcm = msg;
00135 details::ContinuationInvoker *result = NULL;
00136
00137 if (!trapExit)
00138 {
00139 result = m_d_e_p.matchingInvoker(m_lcm);
00140 if (result) return result;
00141 }
00142 for (iter i = m_processors.begin(); i != m_processors.end(); ++i)
00143 {
00144 result = (*i)->matchingInvoker(m_lcm);
00145 if (result) return result;
00146 }
00147 return NULL;
00148 }
00149
00150 }