跨平台c++ Coroutine,仿unity3d实现
不多说,贴代码:
- #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实现的更多相关文章
- Coroutine协同程序介绍(Unity3D开发之三)
猴子原创,欢迎转载.转载请注明: 转载自Cocos2D开发网–Cocos2Dev.com,谢谢! 原文地址: http://www.cocos2dev.com/?p=496 Coroutine在Uni ...
- 在unity3d中使用opencv
1.首先下载opencv2.4.10,解压缩后放在合适的地方,然后根据自己的电脑(32位或64位)选择X86或X64,我的是32位,将“opencv存放路径\build\x86\vc12\bin”加入 ...
- Electron-Vite2-MacUI桌面管理框架|electron13+vue3.x仿mac桌面UI
基于vue3.0.11+electron13仿制macOS桌面UI管理系统ElectronVue3MacUI. 前段时间有分享一个vue3结合electron12开发后台管理系统项目.今天要分享的是最 ...
- 漫谈C#编程语言在游戏领域的应用
0x00 前言 随着微软越来越开放,C#也变得越来越吸引人们的眼球.而在游戏行业中,C#也开始慢慢地获得了关注.这不, 网易绝代双娇手游团队已经全面使用.Net Core支持前后端统一C#开发,跨平台 ...
- Index
我主要在研究.NET/C# 实现 PC IMERP 和 Android IMERP ,目的在解决企业通信中遇到的各类自动化问题 分布式缓存框架: Microsoft Velocity:微软自家分布 ...
- GitHub上整理的一些工具
技术站点 Hacker News:非常棒的针对编程的链接聚合网站 Programming reddit:同上 MSDN:微软相关的官方技术集中地,主要是文档类 infoq:企业级应用,关注软件开发领域 ...
- 推荐书籍 -《移动App测试的22条军规》
在今天的博文中,博主希望给大家分享一本博主同事黄勇的最新利作:<移动App测试的22条军规>.黄勇是ThoughtWorks资深敏捷QA和咨询师.对于我来说,和黄勇在一起的工作的这个项目, ...
- GitHub上整理的一些工具[转载]
Source:http://segmentfault.com/q/1010000002404545 技术站点 Hacker News:非常棒的针对编程的链接聚合网站 Programming reddi ...
- GitHub 开源工具整理
技术站点 Hacker News:非常棒的针对编程的链接聚合网站 Programming reddit:同上 MSDN:微软相关的官方技术集中地,主要是文档类 infoq:企业级应用,关注软件开发领域 ...
随机推荐
- (转)用Eclipse进行C++开发时Bianry not found的问题解决
本文转载自:http://blog.csdn.net/baimafujinji/article/details/49722399 由于Visual Studio体积过于庞大,很多人选择在Eclipse ...
- bzoj 3920: Yuuna的礼物
Description 转眼就要到Karin的生日了!Yuuna她们想为她准备生日礼物!现在有许多礼物被排列成了一个一维序列,每个礼物都有一个价值.Yuuna对这个序列十分感兴趣.因此,你需要多次回答 ...
- Dell vsotro 14 3000系列从win10重装win7
1. F2启动进入新的BIOS界面,首先Disable Secure Boot,然后把UEFI改为Legeacy模式,当然是改不回来的,不知道为什么: 2. 插入U盘(老毛桃+UEFI启动镜像): 3 ...
- TCP/IP四层模型和OSI七层模型的概念
转:http://blog.csdn.net/superjunjin/article/details/7841099/ TCP/IP四层模型 TCP/IP是一组协议的代名词,它还包括许多协议,组成了T ...
- [系统开发] FileMaker进销存系统
一.简介 这是我用 FileMaker 编写的进销存系统: FileMaker 是一种在欧美流行的桌面型数据库:它使用非常方便,功能也很强大,用户可以在它上面开发自己的系统: 开发时间:2008年 二 ...
- eclipse下编译hadoop源代码(转)
hadoop是一个分布式存储和分布式计算的框架.在日常使用hadoop时,我们会发现hadoop不能完全满足我们的需要,我们可能需要修改hadoop的源代码并重新编译.打包. 下面将详细描述如何从sv ...
- DBA_Oracle冷备份案例脚本本法(案例)
2014-08-10 Created By BaoXinjian
- c#复习整理
一.基本语法 1.数据类型 整数类型:int.long 浮点类型:float.double.decimal 布尔类型:bool 字符串类型:string 2.类型转换 int a; double b ...
- ZOJ 3606 Lazy Salesgirl 浙江省第九届省赛
Lazy Salesgirl Time Limit: 5 Seconds Memory Limit: 65536 KB Kochiya Sanae is a lazy girl who ma ...
- image和字节流之间的相互转换
//将图片转化为长二进制 public Byte[] SetImgToByte(string imgPath) { FileStream file = new FileStream(imgPath, ...