管理类 所有的子模块都注册在这个类 这个类使用单例模式 使用回调来通知子模块
.h
#pragma once
#include "GUI.h"
#include "logic.h"
#include <functional>
#include <iostream>
#include <queue>
#include <vector>
#include <memory>
using namespace std;
struct stActionCommand //动作命令结构体
{
int st_CommandFrom; //命令来源
int st_CommandType; //命令类型
int st_CommandSubType; //子命令类型
int st_CommandNumber; //命令编号
int st_Result; //异步执行结果
bool st_SynFlag; //命令同步标识,true时必须等待执行返回,false时放入处理队列
//输入数据
void* st_InData; //复杂输入数据
int st_InEasyData1; //简单输入数据1
int st_InEasyData2; //简单输入数据2
unsigned long st_InULData; //输入无符号长整型
//输出数据
void* st_OutData; //复杂返回数据
int st_OutEasyData1; //简单返回数据1
int st_OutEasyData2; //简单返回数据2
};
class GUI;
class LOGIC;
class CallBackManage {
public:
//单例模式
static CallBackManage& getInstance();
//初始化各个子模块指针
void Init(void);
//回调函数
static void CallBackFunc(void* arg, int commandtype, stActionCommand* msg);
//回调信息处理 但目前本人弃用了 选择在子模块进行异步操作
void commandProcess(stActionCommand* msg);
//提供给主程序的指针 但实际不需要 实际情况会有事件
shared_ptr<void> getGuiPtr();
private:
//构造函数
CallBackManage() {
}
//弃用除构造函数的其他构造 保证线程安全
CallBackManage(const CallBackManage& other) = delete;
CallBackManage& operator =(const CallBackManage& other) = delete;
queue<stActionCommand*> m_queue;
//子模块指针
shared_ptr<GUI> m_guiPtr;
shared_ptr<LOGIC> m_logicPtr;
};
.cpp
#include "CallBackManage.h"
CallBackManage& CallBackManage::getInstance() {
static CallBackManage instance;
return instance;
}
void CallBackManage::Init(void) {
m_guiPtr = make_shared<GUI>();
m_logicPtr = make_shared<LOGIC>();
m_guiPtr->init();
m_logicPtr->init();
}
void CallBackManage::CallBackFunc(void* arg, int commandtype, stActionCommand* msg) {
cout << "CallBack Manage" << endl;
CallBackManage* lp = (CallBackManage*)arg;
cout << lp << "lp" << commandtype << "type" << msg << "msg" << endl;
switch (commandtype) {
case 0:
lp->m_logicPtr->guiButtonClicked(msg);
break;
case 1:
lp->m_guiPtr->LogicReceived(msg);
break;
}
//if (!msg->st_SynFlag) {//异步 这里改为根据type发给子模块比较好 不需要对它进行区分 屏蔽细节
// //或者改为线程池 根据任务的等级进行区分 感觉还是分给模块比较好
// lp->commandProcess(msg);
//}
//else {//同步
//}
}
void CallBackManage::commandProcess(stActionCommand* msg) {
stActionCommand* iTempAC = new stActionCommand;
memcpy(iTempAC, msg, sizeof(stActionCommand));
m_queue.push(iTempAC);
}
shared_ptr<void> CallBackManage::getGuiPtr() {
return m_guiPtr;
}
gui模块.h
#pragma once
#include <functional>
#include <iostream>
#include <queue>
#include <vector>
#include <memory>
#include "CallBackManage.h"
using namespace std;
extern struct stActionCommand;
class GUI {
public:
GUI() {
}
~GUI() {
}
void init();
int ButtonClicked(void);
int LogicReceived(stActionCommand* msg);
private:
function<void(void*, int, stActionCommand*)> m_callBack;
void* m_process;
};
gui模块.cpp
#include "GUI.h"
void GUI::init() {
m_process = &CallBackManage::getInstance();
m_callBack = CallBackManage::CallBackFunc;
}
int GUI::ButtonClicked(void) {
if (m_callBack) {
stActionCommand temp;//生命周期在这一段 回调函数之后 所以回调函数的指针是完全可以的 不会成为悬垂指针
m_callBack(m_process, 0, &temp);
return 0;
}
cout << "empty" << endl;
return -1;
}
int GUI::LogicReceived(stActionCommand* msg) {
cout << "LOGIC handle the msg" << endl;
return 0;
}
logic模块.h
#pragma once
#include <functional>
#include <iostream>
#include <queue>
#include <vector>
#include <memory>
#include "CallBackManage.h"
#include <thread>
using namespace std;
extern struct stActionCommand;
class LOGIC {
public:
LOGIC() {
}
~LOGIC() {
exit = true;
}
void init();
int guiButtonClicked(stActionCommand* msg);
static void asynCommand(void* lobject);
void asynCommandProcess(void);
void processCommand(stActionCommand* msg);
private:
function<void(void*, int, stActionCommand*)> m_callBack;
void* m_process;
queue<stActionCommand*> m_queue;
thread* m_commandAsyn;
bool exit;
};
logic模块.cpp
#include "logic.h"
void LOGIC::init() {
m_process = &CallBackManage::getInstance();
m_callBack = CallBackManage::CallBackFunc;
cout << "size" << m_queue.size() << endl;;
m_commandAsyn = new thread(LOGIC::asynCommand, this);
exit = false;
}
int LOGIC::guiButtonClicked(stActionCommand* msg) {
if (!msg->st_SynFlag) {
stActionCommand* iTempAC = new stActionCommand;
memcpy(iTempAC, msg, sizeof(stActionCommand));
m_queue.push(iTempAC);//然后再启动一个线程来处理这个queue
}
else {
switch (msg->st_CommandType) {
case 0:
cout << "hello i'm hurry" << endl;
break;
}
}
if (m_callBack) {
stActionCommand temp;//生命周期在这一段 回调函数之后
//往temp里面填充信息就行
m_callBack(m_process, 1, &temp);
return 0;
}
cout << " guiButtonClicked empty" << endl;
return -1;
}
void LOGIC::asynCommand(void* lobject) {
LOGIC* lp = (LOGIC*)lobject;
lp->asynCommandProcess();
}
void LOGIC::asynCommandProcess(void) {
while (!exit) {
if (!m_queue.empty())
{
stActionCommand* iTempAC = m_queue.front();
processCommand(iTempAC);
m_queue.pop();
delete iTempAC;
iTempAC = NULL;
}
//_sleep(300);
for (int i = 0; i < 1000 ; i ++) {
}
}
}
void LOGIC::processCommand(stActionCommand* msg) {
switch (msg->st_CommandNumber) {
case 0:
//do something
break;
}
}
test
int main() {
//LOGIC* temp = new LOGIC();
CallBackManage::getInstance();
CallBackManage::getInstance().Init();
auto ptr = static_pointer_cast<GUI>(CallBackManage::getInstance().getGuiPtr());//没办法 只能这样模拟事件了
ptr->ButtonClicked();
system("pause");
return 0;
}