00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef ARCHON_X3D_PROXY_EVENT_H
00021 #define ARCHON_X3D_PROXY_EVENT_H
00022
00023 #include <archon/util/uri.H>
00024
00025 #include <archon/x3d/proxy/session.H>
00026
00027 namespace Archon
00028 {
00029 namespace X3D
00030 {
00031 namespace Proxy
00032 {
00033 struct EventHandlerBase: RefObjectBase
00034 {
00035 protected:
00036 friend struct Session;
00037 virtual void handle(Session *, const x3d::sai::Value &) = 0;
00038 };
00039
00040 template<typename F>
00041 struct EventHandler: EventHandlerBase
00042 {
00043 virtual void handle(typename F::ArgType) = 0;
00044
00045 private:
00046 void handle(Session *s, const x3d::sai::Value &w)
00047 {
00048 typename F::Type v;
00049 s->im(F::index, w, reinterpret_cast<void *>(&v));
00050 handle(v);
00051 }
00052 };
00053
00054 template<typename C>
00055 struct EventHandler<SFNode<C> >: EventHandlerBase
00056 {
00057 typedef SFNode<C> F;
00058
00059 virtual void handle(typename F::ArgType) = 0;
00060
00061 private:
00062 void handle(Session *s, x3d::sai::Value &w)
00063 {
00064 Ref<NodeBase> v;
00065 s->im(F::index, w, reinterpret_cast<void *>(&v));
00066 C *c = dynamic_cast<C *>(v.get());
00067 if(!c) ARCHON_THROW1(Session::ProtocolException,
00068 "Incompatible node type");
00069 handle(v);
00070 }
00071 };
00072
00073 template<typename C>
00074 struct EventHandler<MFNode<C> >: EventHandlerBase
00075 {
00076 typedef MFNode<C> F;
00077
00078 virtual void handle(typename F::ArgType) = 0;
00079
00080 private:
00081 void handle(Session *s, x3d::sai::Value &w)
00082 {
00083 vector<Ref<NodeBase> > v;
00084 s->im(F::index, w, reinterpret_cast<void *>(&v));
00085 vector<Ref<C> > u(v.size());
00086 for(unsigned i=0; i<v.size(); ++i)
00087 {
00088 C *c = dynamic_cast<C *>(v[i].get());
00089 if(!c) ARCHON_THROW1(Session::ProtocolException,
00090 "Incompatible node type");
00091 u[i].reset(c);
00092 }
00093 handle(v);
00094 }
00095 };
00096
00097 template<typename F>
00098 struct FuncCaller: EventHandler<F>
00099 {
00100 void (*f)(typename F::ArgType);
00101 FuncCaller(void (*f)(typename F::ArgType)): f(f) {}
00102
00103 private:
00104 void handle(typename F::ArgType a)
00105 {
00106 (*f)(a);
00107 }
00108 };
00109
00110 template<typename F, typename T>
00111 struct CookieFuncCaller: EventHandler<F>
00112 {
00113 void (*f)(typename F::ArgType, T);
00114 T cookie;
00115 CookieFuncCaller(void (*f)(typename F::ArgType, T), T cookie):
00116 f(f), cookie(cookie) {}
00117
00118 private:
00119 void handle(typename F::ArgType a)
00120 {
00121 (*f)(a, cookie);
00122 }
00123 };
00124 }
00125 }
00126 }
00127
00128 #endif // ARCHON_X3D_PROXY_EVENT_H