Sirikata
liboh/plugins/js/JSObjectStructs/JSTimerStruct.hpp
Go to the documentation of this file.
00001 
00002 #ifndef __SIRIKATA_JS_TIMER_STRUCT_HPP__
00003 #define __SIRIKATA_JS_TIMER_STRUCT_HPP__
00004 
00005 #include "../JSUtil.hpp"
00006 #include "../EmersonScript.hpp"
00007 #include "JSContextStruct.hpp"
00008 #include <v8.h>
00009 #include <sirikata/core/network/IOTimer.hpp>
00010 #include "JSSuspendable.hpp"
00011 #include <sirikata/core/util/Liveness.hpp>
00012 #include "../JSCtx.hpp"
00013 
00014 namespace Sirikata {
00015 
00016 class Context;
00017 
00018 namespace JS {
00019 
00020 struct JSTimerStruct : public JSSuspendable,
00021                        public Liveness
00022 {
00023     JSTimerStruct(EmersonScript* eobj, Duration dur, v8::Persistent<v8::Function>& callback,
00024         JSContextStruct* jscont, uint32 contID,
00025         double timeRemaining, bool isSuspended, bool isCleared, JSCtx* mCtx);
00026     ~JSTimerStruct();
00027 
00028     static JSTimerStruct* decodeTimerStruct(v8::Handle<v8::Value> toDecode,String& errorMessage);
00029 
00030 
00031     v8::Handle<v8::Value> struct_resetTimer(double timeInSecondsToRefire);
00032 private:
00033     void evaluateCallback(Liveness::Token isAlive);
00034 
00035 public:
00036     virtual v8::Handle<v8::Value>suspend();
00037     virtual v8::Handle<v8::Value>resume();
00038     virtual v8::Handle<v8::Value>clear();
00039 
00040     v8::Handle<v8::Value> struct_getAllData();
00041 
00042     EmersonScript* emerScript;
00043     v8::Persistent<v8::Function> cb;
00044     JSContextStruct* jsContStruct;
00045     // Liveness mLiveness;
00046     
00047 private:
00048     JSCtx* mCtx;
00049 
00050     Sirikata::Network::IOTimerPtr mDeadlineTimer;
00051 public:
00052 
00053     Duration timeUntil; //first time create timer will fire after timeUntil seconds
00054     double mTimeRemaining; //when restoring a timer, will fire in this many more
00055                            //seconds.
00056 
00057 
00058     virtual void fixSuspendableToContext(JSContextStruct* toAttachTo);
00059 
00060 
00067     static void timerWeakReferenceCleanup(
00068         v8::Persistent<v8::Value> containsTimer, void* otherArg);
00069 
00081     void noReference(const Liveness::Token &token);
00082 
00087     void setPersistentObject(v8::Persistent<v8::Object>);
00088 
00089 private:
00090 
00097     bool amExecuting;
00098     
00108     bool killAfterFire;
00109 
00113     bool noTimerWaiting;
00114 
00115 
00122     v8::Persistent<v8::Object> mPersistentHandle;
00123 
00124     void iEvaluateCallback(Liveness::Token token);
00125     
00126 };
00127 
00128 struct JSTimerLivenessHolder
00129 {
00130     JSTimerLivenessHolder(JSTimerStruct* jst)
00131      : lt (jst->livenessToken())
00132     {}
00133 
00134     Liveness::Token lt;
00135 };
00136 
00137 
00138 #define INLINE_TIMER_CONV_ERROR(toConvert,whereError,whichArg,whereWriteTo)   \
00139     JSTimerStruct* whereWriteTo;                                                   \
00140     {                                                                      \
00141         String _errMsg = "In " #whereError "cannot convert " #whichArg " to timer struct";     \
00142         whereWriteTo = JSTimerStruct::decodeTimerStruct(toConvert,_errMsg); \
00143         if (whereWriteTo == NULL) \
00144             return v8::ThrowException(v8::Exception::Error(v8::String::New(_errMsg.c_str(), _errMsg.length()))); \
00145     }
00146 
00147 typedef std::map<JSTimerStruct*,int>  TimerMap;
00148 typedef TimerMap::iterator TimerIter;
00149 
00150 }  //end js namespace
00151 }  //end sirikata namespace
00152 
00153 #endif