FAKE_API void fkresumeps(fake * fk, bool & isend) { FKLOG("fkresumeps %p", fk); isend = false; // 上次的processor pool<processor>::node * n = 0; GET_CUR_PROCESSOR(n, fk->rn); if (UNLIKE(!n)) { variant * ret = 0; bool err = false; PS_PUSH_AND_GET(fk->ps, ret); *ret = NILV; FKLOG("fkresumeps %p no processor", fk); CHECK_ERR(err); return; } // 先pop防止重入 POP_CUR_PROCESSOR(fk->rn); processor & pro = n->t; pro.run(); if (LIKE(!PROCESS_END(pro))) { // 重新塞入 PUSH_CUR_PROCESSOR(n, fk->rn); variant * ret = 0; bool err = false; PS_PUSH_AND_GET(fk->ps, ret); *ret = NILV; FKLOG("fkresumeps %p not end", fk); CHECK_ERR(err); return; } // 结束了 variant * ret = 0; bool err = false; PS_PUSH_AND_GET(fk->ps, ret); *ret = ROUTINE_GETRET(*pro.m_entryroutine); CHECK_ERR(err); POOL_PUSH(fk->pp, n); fk->rn.rundeps--; isend = true; FKLOG("fkresumeps %p OK", fk); }
// 调用函数 FAKE_API void fkrunps(fake * fk, const char * func) { FKLOG("fkrunps %p %s", fk, func); fk->rn.rundeps++; // 清空运行环境 fk->clearerr(); // 分配个 pool<processor>::node * n = 0; if (UNLIKE(POOL_EMPTY(fk->pp))) { POOL_GROW(fk->pp, pool<processor>::node, n); PROCESS_INI(n->t, fk); } POOL_POP(fk->pp, n); assert(ARRAY_EMPTY(n->t.m_pl.l)); assert(n->t.m_routine_num == 0); processor & pro = n->t; PROCESS_CLEAR(pro); variant funcv; V_SET_STRING(&funcv, func); routine * r = pro.start_routine(funcv, 0, 0); PUSH_CUR_PROCESSOR(n, fk->rn); // 单独执行,下次再跑run if (UNLIKE(fk->rn.stepmod)) { variant * ret = 0; bool err = false; PS_PUSH_AND_GET(fk->ps, ret); *ret = NILV; FKLOG("fkrunps %p %s yield", fk, func); CHECK_ERR(err); return; } pro.run(); POP_CUR_PROCESSOR(fk->rn); variant * ret = 0; bool err = false; PS_PUSH_AND_GET(fk->ps, ret); *ret = ROUTINE_GETRET(*r); CHECK_ERR(err); POOL_PUSH(fk->pp, n); fk->rn.rundeps--; FKLOG("fkrunps %p %s OK", fk, func); }
void processor::run() { while (m_routine_num > 0) { for (int i = 0; i < (int)ARRAY_SIZE(m_pl.l); i++) { pool<routine>::node * n = ARRAY_GET(m_pl.l, i); if (UNLIKE(!n)) { continue; } // 注意:此函数内部可能会调用到add接口 ROUTINE_RUN(n->t, m_fk->cfg.per_frame_cmd_num); if (UNLIKE(ROUTINE_ISEND(n->t))) { POOL_PUSH(m_pl.p, n); ARRAY_GET(m_pl.l, i) = 0; m_routine_num--; } } } ARRAY_CLEAR(m_pl.l); }