[scripting] add CCNode::scheduleUpdateScriptHandlerWithPriority()

This commit is contained in:
dualface 2012-12-10 13:48:27 +08:00
parent 18f4eb65a5
commit c8753f72ef
9 changed files with 78 additions and 50 deletions

View File

@ -41,32 +41,31 @@ NS_CC_BEGIN
// A list double-linked list used for "updates with priority"
typedef struct _listEntry
{
struct _listEntry *prev, *next;
CCObject *target; // not retained (retained by hashUpdateEntry)
int priority;
struct _listEntry *prev, *next;
CCObject *target; // not retained (retained by hashUpdateEntry)
int priority;
bool paused;
bool markedForDeletion; // selector will no longer be called and entry will be removed at end of the next tick
} tListEntry;
typedef struct _hashUpdateEntry
{
tListEntry **list; // Which list does it belong to ?
tListEntry *entry; // entry in the list
CCObject *target; // hash key (retained)
UT_hash_handle hh;
tListEntry **list; // Which list does it belong to ?
tListEntry *entry; // entry in the list
CCObject *target; // hash key (retained)
UT_hash_handle hh;
} tHashUpdateEntry;
// Hash Element used for "selectors with interval"
typedef struct _hashSelectorEntry
{
ccArray *timers;
ccArray *timers;
CCObject *target; // hash key (retained)
unsigned int timerIndex;
CCTimer *currentTimer;
bool currentTimerSalvaged;
bool paused;
UT_hash_handle hh;
unsigned int timerIndex;
CCTimer *currentTimer;
bool currentTimerSalvaged;
bool paused;
UT_hash_handle hh;
} tHashTimerEntry;
// implementation CCTimer
@ -83,7 +82,6 @@ CCTimer::CCTimer()
, m_fDelay(0.0f)
, m_nScriptHandler(0)
{
}
CCTimer* CCTimer::timerWithTarget(CCObject *pTarget, SEL_SCHEDULE pfnSelector)
@ -152,6 +150,7 @@ void CCTimer::update(float dt)
}
else
{
CCScriptEngineProtocol *pEngine = CCScriptEngineManager::sharedManager()->getScriptEngine();
if (m_bRunForever && !m_bUseDelay)
{//standard timer usage
m_fElapsed += dt;
@ -164,7 +163,7 @@ void CCTimer::update(float dt)
if (m_nScriptHandler)
{
CCScriptEngineManager::sharedManager()->getScriptEngine()->executeSchedule(this, m_fElapsed);
pEngine->executeSchedule(m_nScriptHandler, m_fElapsed);
}
m_fElapsed = 0;
}
@ -183,7 +182,7 @@ void CCTimer::update(float dt)
if (m_nScriptHandler)
{
CCScriptEngineManager::sharedManager()->getScriptEngine()->executeSchedule(this, m_fElapsed);
pEngine->executeSchedule(m_nScriptHandler, m_fElapsed);
}
m_fElapsed = m_fElapsed - m_fDelay;
@ -202,7 +201,7 @@ void CCTimer::update(float dt)
if (m_nScriptHandler)
{
CCScriptEngineManager::sharedManager()->getScriptEngine()->executeSchedule(this, m_fElapsed);
pEngine->executeSchedule(m_nScriptHandler, m_fElapsed);
}
m_fElapsed = 0;
@ -787,15 +786,16 @@ void CCScheduler::update(float dt)
// Iterate over all the Updates' selectors
tListEntry *pEntry, *pTmp;
CCScriptEngineProtocol* pEngine = CCScriptEngineManager::sharedManager()->getScriptEngine();
// updates with priority < 0
DL_FOREACH_SAFE(m_pUpdatesNegList, pEntry, pTmp)
{
if ((! pEntry->paused) && (! pEntry->markedForDeletion))
{
CCScriptEngineProtocol* pEngine = CCScriptEngineManager::sharedManager()->getScriptEngine();
if (pEngine != NULL && kScriptTypeJavascript == pEngine->getScriptType())
{
CCScriptEngineManager::sharedManager()->getScriptEngine()->executeSchedule(NULL, dt, (CCNode *)pEntry->target);
pEngine->executeSchedule(NULL, dt, (CCNode *)pEntry->target);
}
pEntry->target->update(dt);
@ -807,13 +807,12 @@ void CCScheduler::update(float dt)
{
if ((! pEntry->paused) && (! pEntry->markedForDeletion))
{
CCScriptEngineProtocol* pEngine = CCScriptEngineManager::sharedManager()->getScriptEngine();
if (pEngine != NULL && kScriptTypeJavascript == pEngine->getScriptType())
{
CCScriptEngineManager::sharedManager()->getScriptEngine()->executeSchedule(NULL, dt, (CCNode *)pEntry->target);
}
pEntry->target->update(dt);
pEntry->target->update(dt);
}
}
@ -822,13 +821,12 @@ void CCScheduler::update(float dt)
{
if ((! pEntry->paused) && (! pEntry->markedForDeletion))
{
CCScriptEngineProtocol* pEngine = CCScriptEngineManager::sharedManager()->getScriptEngine();
if (pEngine != NULL && kScriptTypeJavascript == pEngine->getScriptType())
{
CCScriptEngineManager::sharedManager()->getScriptEngine()->executeSchedule(NULL, dt, (CCNode *)pEntry->target);
}
pEntry->target->update(dt);
pEntry->target->update(dt);
}
}

View File

@ -81,6 +81,7 @@ CCNode::CCNode(void)
, m_bTransformDirty(true)
, m_bInverseDirty(true)
, m_nScriptHandler(0)
, m_nUpdateScriptHandler(0)
, m_pShaderProgram(NULL)
, m_uOrderOfArrival(0)
, m_eGLServerState(ccGLServerState(0))
@ -102,6 +103,10 @@ CCNode::~CCNode(void)
CCLOGINFO( "cocos2d: deallocing" );
unregisterScriptHandler();
if (m_nUpdateScriptHandler)
{
CCScriptEngineManager::sharedManager()->getScriptEngine()->removeScriptHandler(m_nUpdateScriptHandler);
}
CC_SAFE_RELEASE(m_pActionManager);
CC_SAFE_RELEASE(m_pScheduler);
@ -946,6 +951,16 @@ void CCNode::unregisterScriptHandler(void)
}
}
void CCNode::scheduleUpdateScriptHandlerWithPriority(int nHandler, int priority)
{
if (m_nUpdateScriptHandler)
{
CCScriptEngineManager::sharedManager()->getScriptEngine()->removeScriptHandler(m_nUpdateScriptHandler);
}
m_nUpdateScriptHandler = nHandler;
m_pScheduler->scheduleUpdateForTarget(this, priority, !m_bRunning);
}
void CCNode::setActionManager(CCActionManager* actionManager)
{
if( actionManager != m_pActionManager ) {
@ -1025,6 +1040,11 @@ void CCNode::scheduleUpdateWithPriority(int priority)
void CCNode::unscheduleUpdate()
{
m_pScheduler->unscheduleUpdateForTarget(this);
if (m_nUpdateScriptHandler)
{
CCScriptEngineManager::sharedManager()->getScriptEngine()->removeScriptHandler(m_nUpdateScriptHandler);
m_nUpdateScriptHandler = 0;
}
}
void CCNode::schedule(SEL_SCHEDULE selector)
@ -1079,7 +1099,10 @@ void CCNode::pauseSchedulerAndActions()
// override me
void CCNode::update(float fDelta)
{
if (m_nUpdateScriptHandler)
{
CCScriptEngineManager::sharedManager()->getScriptEngine()->executeSchedule(m_nUpdateScriptHandler, fDelta);
}
}
CCAffineTransform CCNode::nodeToParentTransform(void)

View File

@ -206,7 +206,8 @@ protected:
// script handler
int m_nScriptHandler;
int m_nUpdateScriptHandler;
// script type, lua or javascript
ccScriptType m_eScriptType;
@ -367,6 +368,9 @@ public:
/** Get children count */
unsigned int getChildrenCount(void);
void _setZOrder(int z);
/** Get script handler for onEnter/onExit event. */
inline int getScriptHandler() { return m_nScriptHandler; };
/** get/set Position for Lua (pass number faster than CCPoint object)
@ -379,7 +383,6 @@ public:
node:setPosition(x, y) -- pass x, y values to C++
node:setPositionX(x)
node:setPositionY(y)
node:setPositionInPixels(x, y) -- pass x, y values to C++
*/
const CCPoint& getPositionLua(void);
void getPosition(float* x, float* y);
@ -388,7 +391,6 @@ public:
void setPositionX(float x);
void setPositionY(float y);
void setPosition(float x, float y);
void _setZOrder(int z);
public:
CCNode(void);
@ -640,7 +642,7 @@ public:
delay is the amount of time the action will wait before execution
*/
void schedule(SEL_SCHEDULE selector, float interval, unsigned int repeat, float delay);
/**
Schedules a selector that runs only once, with a delay of 0 or larger
*/
@ -667,7 +669,7 @@ public:
/* Update will be called automatically every frame if "scheduleUpdate" is called, and the node is "live"
*/
virtual void update(float fDelta);
// transformation methods
/** Returns the matrix that transform the node's (local) space coordinates into the parent's space coordinates.
@ -720,7 +722,10 @@ public:
@since v0.7.1
*/
CCPoint convertTouchToNodeSpaceAR(CCTouch * touch);
/** Schedules for script. */
void scheduleUpdateScriptHandlerWithPriority(int nHandler, int priority);
private:
//! lazy allocs
void childrenAlloc(void);
@ -730,7 +735,7 @@ private:
void detachChild(CCNode *child, bool doCleanup);
CCPoint convertToWindowSpace(const CCPoint& nodePoint);
CCPoint convertToWindowSpace(const CCPoint& nodePoint);
};
// end of base_node group

View File

@ -51,9 +51,6 @@ enum ccScriptType {
kScriptTypeJavascript
};
// #pragma mark -
// #pragma mark CCScriptHandlerEntry
class CCScriptHandlerEntry : public CCObject
{
public:
@ -86,9 +83,6 @@ protected:
* @{
*/
// #pragma mark -
// #pragma mark CCSchedulerScriptHandlerEntry
class CCSchedulerScriptHandlerEntry : public CCScriptHandlerEntry
{
public:
@ -128,8 +122,6 @@ private:
};
// #pragma mark -
// #pragma mark CCTouchScriptHandlerEntry
class CCTouchScriptHandlerEntry : public CCScriptHandlerEntry
{
@ -164,8 +156,6 @@ private:
bool m_bSwallowsTouches;
};
// #pragma mark -
// #pragma mark CCScriptEngineProtocol
// Don't make CCScriptEngineProtocol inherits from CCObject since setScriptEngine is invoked only once in AppDelegate.cpp,
// It will affect the lifecycle of ScriptCore instance, the autorelease pool will be destroyed before destructing ScriptCore.
@ -222,6 +212,7 @@ public:
virtual int executeCallFuncActionEvent(CCCallFunc* pAction, CCObject* pTarget = NULL) = 0;
/** execute a schedule function */
virtual int executeSchedule(CCTimer* pTimer, float dt, CCNode* pNode = NULL) = 0;
virtual int executeSchedule(int nHandler, float dt, CCNode* pNode = NULL) = 0;
/** functions for executing touch event */
virtual int executeLayerTouchesEvent(CCLayer* pLayer, int eventType, CCSet *pTouches) = 0;

View File

@ -713,17 +713,22 @@ int ScriptingCore::executeCallFuncActionEvent(CCCallFunc* pAction, CCObject* pTa
}
int ScriptingCore::executeSchedule(CCTimer* pTimer, float dt, CCNode* pNode/* = NULL*/)
{
executeSchedule(0, dt, pNode)
}
int ScriptingCore::executeSchedule(int nHandler, float dt, CCNode* pNode/* = NULL*/)
{
js_proxy_t * p;
JS_GET_PROXY(p, pNode);
if (!p) return 0;
jsval retval;
jsval dataVal = DOUBLE_TO_JSVAL(dt);
executeJSFunctionWithName(this->cx_, p->obj, "update", dataVal, retval);
return 1;
}

View File

@ -81,6 +81,7 @@ public:
virtual int executeNotificationEvent(CCNotificationCenter* pNotificationCenter, const char* pszName);
virtual int executeCallFuncActionEvent(CCCallFunc* pAction, CCObject* pTarget = NULL);
virtual int executeSchedule(CCTimer* pTimer, float dt, CCNode* pNode = NULL);
virtual int executeSchedule(int nHandler, float dt, CCNode* pNode = NULL);
virtual int executeLayerTouchesEvent(CCLayer* pLayer, int eventType, CCSet *pTouches);
virtual int executeLayerTouchEvent(CCLayer* pLayer, int eventType, CCTouch *pTouch);
virtual int executeAccelerometerEvent(CCLayer* pLayer, CCAcceleration* pAccelerationValue);

View File

@ -389,6 +389,13 @@ int CCLuaEngine::executeSchedule(CCTimer* pTimer, float dt, CCNode* pNode/* = NU
return ret;
}
int CCLuaEngine::executeSchedule(int nHandler, float dt, CCNode* pNode/* = NULL*/)
{
cleanStack();
pushFloat(dt);
return executeFunctionByHandler(nHandler, 1);
}
// functions for excute touch event
int CCLuaEngine::executeLayerTouchEvent(CCLayer* pLayer, int eventType, CCTouch *pTouch)
{

View File

@ -193,6 +193,7 @@ public:
virtual int executeNotificationEvent(CCNotificationCenter* pNotificationCenter, const char* pszName);
virtual int executeCallFuncActionEvent(CCCallFunc* pAction, CCObject* pTarget = NULL);
virtual int executeSchedule(CCTimer* pTimer, float dt, CCNode* pNode = NULL);
virtual int executeSchedule(int nHandler, float dt, CCNode* pNode = NULL);
virtual int executeLayerTouchesEvent(CCLayer* pLayer, int eventType, CCSet *pTouches);
virtual int executeLayerTouchEvent(CCLayer* pLayer, int eventType, CCTouch *pTouch);
virtual int executeLayerKeypadEvent(CCLayer* pLayer, int eventType);

View File

@ -47,9 +47,6 @@ class CCNode : public CCObject
CCCamera* getCamera();
CCGridBase* getGrid();
void setGrid(CCGridBase* pGrid);
//CCPoint getAnchorPointInPixels();
//CCSize getContentSizeInPixels();
//void setContentSizeInPixels(CCSize sz);
CCPoint getAnchorPointInPoints();
bool isRunning();
CCNode* getParent();
@ -111,7 +108,7 @@ class CCNode : public CCObject
void removeFromParentAndCleanup(bool cleanup);
void removeChildByTag(int tag, bool cleanup);
void scheduleUpdate(void);
void scheduleUpdateScriptHandlerWithPriority(LUA_FUNCTION nHandler, int priority);
void unscheduleUpdate(void);
void registerScriptHandler(LUA_FUNCTION funcID);