cxAny cxActionRootCreate(cxConstChars xml) { cxEngine engine = cxEngineInstance(); cxActionRoot this = cxHashGet(engine->actions, cxHashStrKey(xml)); if(this != NULL){ return this; } cxXMLScript script = cxEngineGetXMLScript(xml); if(script == NULL || script->bytes == NULL){ CX_ERROR("%s script not register",xml); return NULL; } this = CX_CREATE(cxActionRoot); xmlTextReaderPtr reader = cxXMLReaderForScript(script,cxActionRootReaderError, this); if(reader == NULL){ CX_ERROR("create xml reader failed"); return NULL; } CX_EVENT_FIRE(this, onBegin); cxActionRootLoadCodesWithReader(this, reader); cxHashKey key = cxHashStrKey(xml); cxHashSet(this->codes, key, script->bytes); cxHashSet(engine->actions, key, this); CX_EVENT_FIRE(this, onEnd); return this; }
CX_METHOD_DEF(cxSpline,Step,void,cxFloat dt,cxFloat time) { cxInt index = 0; CX_ASSERT_VALUE(cxActionGetView(this), cxView, view); cxFloat lt = 0; if (time >= 1.0f){ index = cxAnyArrayLength(this->points) - 1; lt = 1.0f; }else{ index = time / this->delta; lt = (time - this->delta * (cxFloat)index) / this->delta; } if(index != this->index){ this->index = index; CX_EVENT_FIRE(this, onIndex); } cxVec2f p0 = cxSplinePointAt(this, index - 1); cxVec2f p1 = cxSplinePointAt(this, index + 0); cxVec2f p2 = cxSplinePointAt(this, index + 1); cxVec2f p3 = cxSplinePointAt(this, index + 2); cxVec2f newpos = cxCardinalSplineAt(p0, p1, p2, p3, this->tension, lt); cxVec2f vpos = cxViewGetPosition(view); cxVec2f diff = cxVec2fSub(vpos, this->prev); if(diff.x != 0 || diff.y != 0){ this->diff = cxVec2fAdd(this->diff, diff); newpos = cxVec2fAdd(newpos, this->diff); } cxFloat angle = cxVec2fRadiansBetween(newpos, this->prev); if(!cxFloatEqu(angle, this->angle)){ this->angle = angle; CX_EVENT_FIRE(this, onAngle); } cxViewSetPosition(view, newpos); this->prev = newpos; }
static void cxLoadingArrive(cxEvent *event) { cxLoading this = cxActionView(event->sender); CX_EVENT_FIRE(this, onLoading); cxTimer timer = cxViewAppendTimer(this, 1.0f, 1); CX_EVENT_QUICK(timer->onArrive, cxFinishedArrive); }
void cxLoadingOnUpdate(cxEvent *event) { cxLoading this = event->sender; if(this->isLoading){ CX_EVENT_FIRE(this, onFinished); cxViewRemoved(this); } }
static cxBool cxTimerExit(cxAny pav) { cxTimer this = pav; if(this->repeat > 0){ this->repeat --; } CX_EVENT_FIRE(this, onArrive); return this->repeat == 0; }
static void cxClippingDrawBefore(cxAny pview) { cxClipping this = pview; glEnable(GL_STENCIL_TEST); glStencilFunc(GL_ALWAYS, this->useRef, CX_STENCIL_MASK); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); CX_EVENT_FIRE(this, onClipping); glStencilFunc(this->inverse ? GL_NOTEQUAL : GL_EQUAL, this->useRef, CX_STENCIL_MASK); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); }
void cxEngineExit() { CX_RETURN(isExit); cxEngine engine = cxEngineInstance(); CX_EVENT_FIRE(engine, onExit); cxEnginePause(); cxEngineDestroy(); cxAllocatorFree(); cxEngineTerminate(); isExit = true; }
static void cxTimeLineStep(cxAny pav,cxFloat dt,cxFloat time) { cxTimeLine this = pav; cxInt count = cxArrayLength(this->times); for(cxInt i = this->index + 1; i < count; i++){ cxNumber num = cxArrayAtIndex(this->times, i); cxFloat time = cxNumberToFloat(num); if(this->cxAction.durationElapsed >= time){ this->index = i; CX_EVENT_FIRE(this, onTime); continue; } break; } if(this->index == (count - 1)){ cxActionStop(this); } }
CX_METHOD_DEF(cxSpline,Init,void) { CX_ASSERT_VALUE(cxActionGetView(this), cxView, view); cxInt num = cxAnyArrayLength(this->points); if(num < 2){ cxActionStop(this); return; } this->delta = 1.0f/((cxFloat)num - 1.0f); this->diff = cxVec2fv(0, 0); this->prev =cxViewGetPosition(view); cxVec2f p0 = cxSplinePointAt(this, 0); cxVec2f p1 = cxSplinePointAt(this, num - 1); cxFloat angle = cxVec2fRadiansBetween(p1, p0); if(!cxFloatEqu(angle, this->angle)){ this->angle = angle; CX_EVENT_FIRE(this, onAngle); } CX_SUPER(cxAction, this, Init, CX_M(void)); }
cxBool cxButtonTouch(cxAny pview,cxTouch *touch) { cxButton this = pview; if(!this->isEnable){ return false; } cxBool hit = cxViewHitTest(pview, touch->current, NULL); if(!hit && this->isDown){ CX_EVENT_FIRE(this, onLeave); this->isDown = false; } if(!hit){ return false; } if(touch->type == cxTouchTypeDown){ this->isDown = true; CX_EVENT_FIRE(this, onEnter); CX_EVENT_FIRE(this, onPress); return true; } if(!this->isDown){ return false; } if(touch->type == cxTouchTypeMove && cxVec2fMagnitude(touch->movement) > this->movement){ CX_EVENT_FIRE(this, onLeave); this->isDown = false; return false; } if(touch->type == cxTouchTypeUp){ this->isDown = false; CX_EVENT_FIRE(this, onRelease); CX_EVENT_FIRE(this, onLeave); return true; } return false; }
cxBool cxActionUpdate(cxAny pav,cxFloat dt) { cxAction this = pav; cxBool isExit = false; dt = dt * this->speed; if(this->isPause || this->isExit){ goto finished; } //action delay this->delayElapsed += dt; if(this->delay > 0 && this->delayElapsed < this->delay){ goto finished; } //init event if(!this->isFirst){ this->isFirst = true; CX_ASSERT(this->view != NULL, "action viewptr null"); this->prevTime = 0; this->delayElapsed = 0; this->durationElapsed = this->durationInit; CX_METHOD_FIRE(NULL, this->Init, this); CX_EVENT_FIRE(this, onStart); } //for active if(!this->isActive){ this->isActive = true; CX_METHOD_FIRE(NULL, this->Active, this); } this->durationElapsed += dt; cxFloat value = this->durationElapsed/CX_MAX(this->duration, FLT_EPSILON); cxFloat time = kmClamp(value, 0.0f, 1.0f); //split index event fire cxInt index = -1; if(time >= 1.0f){ index = this->split - 1; }else if(this->splitDelta > 0){ index = time / this->splitDelta; } if(this->index != index && index >= 0){ this->index = index; CX_EVENT_FIRE(this,onSplit); } //wait exit if(this->duration < 0){ CX_METHOD_FIRE(NULL, this->Step,this,dt,time); CX_EVENT_FIRE(this, onStep); }else if(this->duration == 0){ isExit = CX_METHOD_FIRE(true, this->Exit, this); }else if(this->durationElapsed < this->duration){ time = CX_METHOD_FIRE(time, this->Curve, this, time); this->delta = time - this->prevTime; this->prevTime = time; CX_METHOD_FIRE(NULL, this->Step,this,dt,time); CX_EVENT_FIRE(this, onStep); }else{ time = CX_METHOD_FIRE(1.0f, this->Curve,this,1.0f); this->delta = time - this->prevTime; this->prevTime = 0; this->durationElapsed = 0.0f; this->delayElapsed = 0.0f; CX_METHOD_FIRE(NULL, this->Step,this,dt,1.0f); CX_EVENT_FIRE(this, onStep); //check exit isExit = CX_METHOD_FIRE(true, this->Exit,this); this->isActive = false; } //check action exit finished: //force exit or auto exit if(this->isExit || isExit){ CX_EVENT_FIRE(this, onStop); CX_METHOD_FIRE(NULL, this->Over,this); } return (this->isExit || isExit); }