跨平台c++ Coroutine,仿unity3d实现
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了跨平台c++ Coroutine,仿unity3d实现,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5713字,纯文字阅读大概需要9分钟。
内容图文
不多说,贴代码:
4 #include "stdafx.h" 5 #include <list> 6 #include <thread> 7 #include <chrono> 8 9struct ICoroutine 10{ 11virtualvoid reset(){} 12virtualbool move_next(int & r, float & fv) { returnfalse; } 13virtual ~ICoroutine() {} 14public: 15float mWaitSeconds; 16}; 17 18 template<typename T> 19struct _IGenerator : public ICoroutine 20{ 21 T* _stack; 22int _line; 23 _IGenerator() :_stack(0), _line(-1) {} 24virtualvoid reset() 25 { 26 _line = -1; 27 } 28void _push() { T* n = new T; *n = *static_cast<T*>(this); _stack = n; } 29bool _pop() { if (!_stack) returnfalse; T* t = _stack; *static_cast<T*>(this) = *_stack; t->_stack = 0; delete t; returntrue; } 30 ~_IGenerator() { while (_pop()); } 31}; 32 33#define $coroutine(NAME) struct NAME : public _IGenerator<NAME> 34 35 36#define $begin virtual bool move_next(int& _rv, float& _rv2) { 37if(_line < 0) _line=0; 38 $START: switch(_line) { case0:; 39 40#define $stop } _line = 0; if(_pop()) goto $START; return false; } 41 42#define $restart(WITH) { _push(); _stack->_line = __LINE__; _line=0; WITH; goto $START; case __LINE__:; } 43 44#define $yield(V) 45do { 46 _line=__LINE__; 47 _rv = (V); returntrue; case __LINE__:; 48 } while (0) 49 50#define $yield_f(V, V2) 51do { 52 _line=__LINE__; 53 _rv = (V); _rv2 = V2; returntrue; case __LINE__:; 54 } while (0) 55 56 57enum CoroutineState 58{ 59 CO_None, 60 CO_WaitForNextUpdate, 61 CO_WaitForSeconds, 62 CO_Exit 63}; 64 65class GScheduler 66{ 67protected: 68 std::list<ICoroutine *> mActivityGList; 69 std::list<ICoroutine *> mWaitingGList; 70 std::list<ICoroutine *> mDeadingGList; 71 72 std::list<ICoroutine *> mGList; 73 74void DestroyAllCoroutine() 75 { 76 std::list<ICoroutine *>::iterator iter; 77for (iter = mGList.begin(); iter != mGList.end(); iter++) 78 { 79 ICoroutine * co = *iter; 80delete co; 81 } 82 mGList.clear(); 83 mDeadingGList.clear(); 84 mWaitingGList.clear(); 85 mActivityGList.clear(); 86 } 87public: 88 ~GScheduler() 89 { 90 DestroyAllCoroutine(); 91 } 92 93 94 template<typename T, typename T2> 95 ICoroutine* StartCoroutine(T2 * tObj) 96 { 97 ICoroutine * gen = new T(tObj); 98 mGList.push_back(gen); 99 mActivityGList.push_back(gen); 100return gen; 101 } 102103void StopCoroutine(ICoroutine *) 104 { 105 } 106107void RestartAllCoroutine() 108 { 109 std::list<ICoroutine *>::iterator iter; 110for (iter = mGList.begin(); iter != mGList.end(); iter++) 111 { 112 ICoroutine * co = *iter; 113 co->reset(); 114 mActivityGList.push_back(co); 115 } 116 } 117118void StopAllCoroutine() 119 { 120 mDeadingGList.clear(); 121 mWaitingGList.clear(); 122 mActivityGList.clear(); 123 } 124void UpdateAllCoroutine(float dt) 125 { 126 std::list<ICoroutine *>::iterator iter, next; 127for (iter = mWaitingGList.begin(); iter != mWaitingGList.end();iter = next) 128 { 129 next = iter; next++; 130131 ICoroutine * co = *iter; 132 co->mWaitSeconds -= dt; 133if (co->mWaitSeconds <= 0) 134 { 135 next = mWaitingGList.erase(iter); 136 mActivityGList.push_back(co); 137 } 138 } 139140for (iter = mActivityGList.begin(); iter != mActivityGList.end(); iter = next) 141 { 142 next = iter; next++; 143144 ICoroutine * co = *iter; 145146bool isDeading = false; 147148int retValue = 0; 149float retFValue = 0; 150if (!co->move_next(retValue, retFValue)) 151 { 152 isDeading = true; 153 } 154 CoroutineState state = (CoroutineState)retValue; 155if (state == CO_Exit) 156 { 157 isDeading = true; 158 } 159elseif (state == CO_WaitForNextUpdate) 160 { 161162 } 163elseif (state == CO_WaitForSeconds) 164 { 165float seconds = retFValue; 166 co->mWaitSeconds = seconds; 167 next = mActivityGList.erase(iter); 168 mWaitingGList.push_back(co); 169 } 170171if (isDeading) 172 { 173 next = mActivityGList.erase(iter); 174 mDeadingGList.push_back(co); 175 } 176 } 177 } 178}; 179 //**********************************************************************************************************
//以下是测试程序: 180class TestCoroutine1; 181class TestCoroutine2; 182class UIMain : public GScheduler 183{ 184public: 185 UIMain() 186 { 187 } 188void Enable() 189 { 190 RestartAllCoroutine(); 191 } 192void Disable() 193 { 194 StopAllCoroutine(); 195 } 196197void Start() 198 { 199 ICoroutine *testCo = StartCoroutine<TestCoroutine1, UIMain>(this); 200 StartCoroutine<TestCoroutine2, UIMain>(this); 201 } 202203void Update(float dt) 204 { 205 UpdateAllCoroutine(dt); 206 } 207208void Test1(int v) 209 { 210 printf("Test1, v = %d\n", v); 211 } 212void Test2(int v) 213 { 214 printf("Test2, v = %d\n", v); 215 } 216}; 217218219$coroutine(TestCoroutine1) 220{ 221 UIMain* n; 222 TestCoroutine1(UIMain* root = 0) : n(root) {} 223int i = 0; 224 $begin 225for (i = 0; i < 3; i++) 226 { 227 n->Test1(i); 228 $yield(CO_WaitForNextUpdate); 229 } 230 $yield(CO_Exit); 231 n->Test1(10); 232 $stop 233}; 234235$coroutine(TestCoroutine2) 236{ 237 UIMain* n; 238 TestCoroutine2(UIMain* root = 0) : n(root) {} 239int i = 0; 240 $begin 241for (i = 3; i < 6; i++) 242 { 243 n->Test2(i); 244 $yield_f(CO_WaitForSeconds, 0.5f); 245 } 246 $yield(CO_Exit); 247 n->Test1(99); 248 $stop 249}; 250251252253int _tmain(int argc, _TCHAR* argv[]) 254{ 255 UIMain uiMain; 256257 uiMain.Enable(); 258 uiMain.Start(); 259260float dt = 0.05f; 261float time = 0; 262while (true) 263 { 264 uiMain.Update(dt); 265 std::this_thread::sleep_for(std::chrono::milliseconds((int)(dt*1000))); 266 time += dt; 267if (time > 10) //10秒后重开协程268 { 269 uiMain.Disable(); 270 uiMain.Enable(); //重新开始协程 271 time = 0; 272 } 273 } 274return0; 275 }
原文:http://www.cnblogs.com/corefans/p/4763723.html
内容总结
以上是互联网集市为您收集整理的跨平台c++ Coroutine,仿unity3d实现全部内容,希望文章能够帮你解决跨平台c++ Coroutine,仿unity3d实现所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。