不多说,贴代码:

 #include "stdafx.h"
#include <list>
#include <thread>
#include <chrono> struct ICoroutine
{
virtual void reset(){}
virtual bool move_next(int & r, float & fv) { return false; }
virtual ~ICoroutine() {}
public:
float mWaitSeconds;
}; template<typename T>
struct _IGenerator : public ICoroutine
{
T* _stack;
int _line;
_IGenerator() :_stack(), _line(-) {}
virtual void reset()
{
_line = -;
}
void _push() { T* n = new T; *n = *static_cast<T*>(this); _stack = n; }
bool _pop() { if (!_stack) return false; T* t = _stack; *static_cast<T*>(this) = *_stack; t->_stack = ; delete t; return true; }
~_IGenerator() { while (_pop()); }
}; #define $coroutine(NAME) struct NAME : public _IGenerator<NAME> #define $begin virtual bool move_next(int& _rv, float& _rv2) { \
if(_line < ) _line=; \
$START: switch(_line) { case :; #define $stop } _line = 0; if(_pop()) goto $START; return false; } #define $restart(WITH) { _push(); _stack->_line = __LINE__; _line=0; WITH; goto $START; case __LINE__:; } #define $yield(V) \
do {\
_line=__LINE__;\
_rv = (V); return true; case __LINE__:;\
} while () #define $yield_f(V, V2) \
do {\
_line=__LINE__;\
_rv = (V); _rv2 = V2; return true; case __LINE__:;\
} while () enum CoroutineState
{
CO_None,
CO_WaitForNextUpdate,
CO_WaitForSeconds,
CO_Exit
}; class GScheduler
{
protected:
std::list<ICoroutine *> mActivityGList;
std::list<ICoroutine *> mWaitingGList;
std::list<ICoroutine *> mDeadingGList; std::list<ICoroutine *> mGList; void DestroyAllCoroutine()
{
std::list<ICoroutine *>::iterator iter;
for (iter = mGList.begin(); iter != mGList.end(); iter++)
{
ICoroutine * co = *iter;
delete co;
}
mGList.clear();
mDeadingGList.clear();
mWaitingGList.clear();
mActivityGList.clear();
}
public:
~GScheduler()
{
DestroyAllCoroutine();
} template<typename T, typename T2>
ICoroutine* StartCoroutine(T2 * tObj)
{
ICoroutine * gen = new T(tObj);
mGList.push_back(gen);
mActivityGList.push_back(gen);
return gen;
} void StopCoroutine(ICoroutine *)
{
} void RestartAllCoroutine()
{
std::list<ICoroutine *>::iterator iter;
for (iter = mGList.begin(); iter != mGList.end(); iter++)
{
ICoroutine * co = *iter;
co->reset();
mActivityGList.push_back(co);
}
} void StopAllCoroutine()
{
mDeadingGList.clear();
mWaitingGList.clear();
mActivityGList.clear();
}
void UpdateAllCoroutine(float dt)
{
std::list<ICoroutine *>::iterator iter, next;
for (iter = mWaitingGList.begin(); iter != mWaitingGList.end();iter = next)
{
next = iter; next++; ICoroutine * co = *iter;
co->mWaitSeconds -= dt;
if (co->mWaitSeconds <= )
{
next = mWaitingGList.erase(iter);
mActivityGList.push_back(co);
}
} for (iter = mActivityGList.begin(); iter != mActivityGList.end(); iter = next)
{
next = iter; next++; ICoroutine * co = *iter; bool isDeading = false; int retValue = ;
float retFValue = ;
if (!co->move_next(retValue, retFValue))
{
isDeading = true;
}
CoroutineState state = (CoroutineState)retValue;
if (state == CO_Exit)
{
isDeading = true;
}
else if (state == CO_WaitForNextUpdate)
{ }
else if (state == CO_WaitForSeconds)
{
float seconds = retFValue;
co->mWaitSeconds = seconds;
next = mActivityGList.erase(iter);
mWaitingGList.push_back(co);
} if (isDeading)
{
next = mActivityGList.erase(iter);
mDeadingGList.push_back(co);
}
}
}
};
//**********************************************************************************************************
//以下是测试程序:
class TestCoroutine1;
class TestCoroutine2;
class UIMain : public GScheduler
{
public:
UIMain()
{
}
void Enable()
{
RestartAllCoroutine();
}
void Disable()
{
StopAllCoroutine();
} void Start()
{
ICoroutine *testCo = StartCoroutine<TestCoroutine1, UIMain>(this);
StartCoroutine<TestCoroutine2, UIMain>(this);
} void Update(float dt)
{
UpdateAllCoroutine(dt);
} void Test1(int v)
{
printf("Test1, v = %d\n", v);
}
void Test2(int v)
{
printf("Test2, v = %d\n", v);
}
}; $coroutine(TestCoroutine1)
{
UIMain* n;
TestCoroutine1(UIMain* root = ) : n(root) {}
int i = ;
$begin
for (i = ; i < ; i++)
{
n->Test1(i);
$yield(CO_WaitForNextUpdate);
}
$yield(CO_Exit);
n->Test1();
$stop
}; $coroutine(TestCoroutine2)
{
UIMain* n;
TestCoroutine2(UIMain* root = ) : n(root) {}
int i = ;
$begin
for (i = ; i < ; i++)
{
n->Test2(i);
$yield_f(CO_WaitForSeconds, 0.5f);
}
$yield(CO_Exit);
n->Test1();
$stop
}; int _tmain(int argc, _TCHAR* argv[])
{
UIMain uiMain; uiMain.Enable();
uiMain.Start(); float dt = 0.05f;
float time = ;
while (true)
{
uiMain.Update(dt);
std::this_thread::sleep_for(std::chrono::milliseconds((int)(dt*)));
time += dt;
if (time > ) //10秒后重开协程
{
uiMain.Disable();
uiMain.Enable(); //重新开始协程
time = ;
}
}
return ;
}

跨平台c++ Coroutine,仿unity3d实现的更多相关文章

  1. Coroutine协同程序介绍(Unity3D开发之三)

    猴子原创,欢迎转载.转载请注明: 转载自Cocos2D开发网–Cocos2Dev.com,谢谢! 原文地址: http://www.cocos2dev.com/?p=496 Coroutine在Uni ...

  2. 在unity3d中使用opencv

    1.首先下载opencv2.4.10,解压缩后放在合适的地方,然后根据自己的电脑(32位或64位)选择X86或X64,我的是32位,将“opencv存放路径\build\x86\vc12\bin”加入 ...

  3. Electron-Vite2-MacUI桌面管理框架|electron13+vue3.x仿mac桌面UI

    基于vue3.0.11+electron13仿制macOS桌面UI管理系统ElectronVue3MacUI. 前段时间有分享一个vue3结合electron12开发后台管理系统项目.今天要分享的是最 ...

  4. 漫谈C#编程语言在游戏领域的应用

    0x00 前言 随着微软越来越开放,C#也变得越来越吸引人们的眼球.而在游戏行业中,C#也开始慢慢地获得了关注.这不, 网易绝代双娇手游团队已经全面使用.Net Core支持前后端统一C#开发,跨平台 ...

  5. Index

    我主要在研究.NET/C# 实现 PC IMERP 和 Android IMERP ,目的在解决企业通信中遇到的各类自动化问题   分布式缓存框架: Microsoft Velocity:微软自家分布 ...

  6. GitHub上整理的一些工具

    技术站点 Hacker News:非常棒的针对编程的链接聚合网站 Programming reddit:同上 MSDN:微软相关的官方技术集中地,主要是文档类 infoq:企业级应用,关注软件开发领域 ...

  7. 推荐书籍 -《移动App测试的22条军规》

    在今天的博文中,博主希望给大家分享一本博主同事黄勇的最新利作:<移动App测试的22条军规>.黄勇是ThoughtWorks资深敏捷QA和咨询师.对于我来说,和黄勇在一起的工作的这个项目, ...

  8. GitHub上整理的一些工具[转载]

    Source:http://segmentfault.com/q/1010000002404545 技术站点 Hacker News:非常棒的针对编程的链接聚合网站 Programming reddi ...

  9. GitHub 开源工具整理

    技术站点 Hacker News:非常棒的针对编程的链接聚合网站 Programming reddit:同上 MSDN:微软相关的官方技术集中地,主要是文档类 infoq:企业级应用,关注软件开发领域 ...

随机推荐

  1. 【python】禁止print输出换行的方法

    print后用一个逗号结尾就可以禁止输出换行,例子如下 >>> i=0 >>> while i < 3: print i i+=1 0 1 2 禁止输出换行后 ...

  2. 一个问题提交的实例(js原生动画,原生ajax,js引用加参数)

    document.writeln("<div id=\"tanchuangwai\" class=\"tanchuangwai\" style= ...

  3. 在Ubuntu下编译wpa_supplicant

    最近在研究WiFi联盟的多屏互动协议Miracast,其中需要用到wpa_supplicant,编译中遇到了一些问题,经过一下午的折腾也都解决了,下面分享给各位. 一.编译需要用到三个库源码包,分别是 ...

  4. 几个关于wcf、rest服务的好帖子

    //http://blog.csdn.net/fangxing80/article/details/6247297  //http://msdn.microsoft.com/zh-cn/magazin ...

  5. 我的IT相关网址收藏

    it语言学习免费视频: 尚学堂:http://www.sxt.cn/ 慕课网:http://www.imooc.com/course/list 大学生自学网:http://v.dxsbb.com/ 尚 ...

  6. C#使用ConditionalAttribute特性来实现代码调试

    转自:http://www.csharpwin.com/csharpspace/10729r8541.shtml #if/#endif条件编译常用来由同一份源代码生成不同的结果文件,最常见的有debu ...

  7. 黄聪:wordpress如何使用wp_rewrite实现自定义伪静态,非301重定向。

    今天,想通过wordpress实现 http://hcsem.com/a?h-1 伪静态为 http://hcsem.com/a-1.html 找了很多资料,终于搞定. 只需要在functions.p ...

  8. IGS_学习笔记08_IREP通过soapUI测试客户化Web Service调用(案例)

    20150819 Created By BaoXinjian

  9. NeHe OpenGL教程 第四十一课:体积雾气

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  10. python (10) 文件夹的创建与文件夹的删除

    有时需要在代码中对文件或者文件夹 进行删除,或者添加 导入的包:import os,shutil 新建文件夹 import os,shutil path = os.getcwd() #获得当前目录 # ...