GithubHelp home page GithubHelp logo

Comments (3)

wqking avatar wqking commented on August 15, 2024

The code is fine. Please show full code that includes the enque and start the thread.

from eventpp.

RWBYBING avatar RWBYBING commented on August 15, 2024

I am developing a desktop application with a GUI, and I plan to use eventpp as the communication method between the various modules of the software.

First of all, I encapsulate the eventpp part into a class called EventManager. There is a StartEventLoop function which starts the thread. Here is the full code of the class:

## "EventManager.h"

#pragma once

#include <iostream>
#include <mutex>
#include <Utils/EventManager/EventType.h>
#include <eventpp/eventdispatcher.h>
#include <eventpp/eventqueue.h>

class EventManager
{
public:
	// 获取单例实例
	static std::shared_ptr<EventManager> getInstance();
	// 销毁实例
	static void destroyInstance(EventManager* x);

private:
	static std::shared_ptr<EventManager> _instance;
	static std::mutex _mutex;
	EventManager();
	~EventManager();
	EventManager(const EventManager&) = delete;
	void operator=(const EventManager&) = delete;

public:
	// 事件发布
	void EventPublish(EventType type, const std::shared_ptr<Event> event);
	// 事件订阅
	void EventSubscribe(EventType type, std::function<void(const std::shared_ptr<Event>)> listener);
	// 开启事件监听循环
	void StartEventLoop();

private:
	// 异步事件队列
	std::unique_ptr<eventpp::EventQueue<EventType, void(const std::shared_ptr<Event>&), EventPolicies>> eventQueue;
};

## "EventManager.cpp"
#include <Utils/EventManager/EventManager.h>

std::shared_ptr<EventManager> EventManager::_instance;
std::mutex EventManager::_mutex;

EventManager::EventManager()
	: eventQueue(std::make_unique<eventpp::EventQueue<EventType, void(const std::shared_ptr<Event>&), EventPolicies>>())
{

}

void EventManager::StartEventLoop()
{
    try {
        std::thread thread([this]() {
            volatile bool _eventqueue_should_stop = false;
            std::cout << "Event Listening Thread Started" << std::endl;

            // 监听关闭事件系统的事件
            this->EventSubscribe(EventType::E_STOP_EVENT_QUEUE, [&_eventqueue_should_stop](std::shared_ptr<Event>) {
            	_eventqueue_should_stop = true;
            });

            while (!_eventqueue_should_stop)
            {
            	eventQueue->wait();
            	eventQueue->process();
            }

            std::cout << "Evnt Listening Thread Stopped" << std::endl;
        });
        thread.detach();
    }
    catch (const std::exception& e) {
        // 捕获异常
        std::cerr << "Caught exception in StartEventLoop(): " << e.what() << std::endl;
    }
}

EventManager::~EventManager()
{
	// TODO: 发布STOP_EVENT
}

std::shared_ptr<EventManager> EventManager::getInstance()
{
	// 若为空则创建
	if (_instance == nullptr)
	{
		// 加锁保证线程安全
		std::lock_guard<std::mutex> l(_mutex);
		if (_instance == nullptr)
		{
			_instance.reset(new EventManager(), destroyInstance);
		}
	}
	return _instance;
}

void EventManager::destroyInstance(EventManager* x)
{
	delete x;
}

void EventManager::EventPublish(EventType type, const std::shared_ptr<Event> event)
{
	eventQueue->enqueue(event);
}

void EventManager::EventSubscribe(EventType type, std::function<void(const std::shared_ptr<Event>)> listener)
{
	eventQueue->appendListener(type, listener);
}

Afterwards, in the GUI thread(which is also the main thread), I enqueued the event:

	// 搜索雷达按钮
	ImGui::SetCursorPosX((windowWidth - closeButtonWidth) * 0.3333f);
	ImGui::SetCursorPosY((windowHeight * 0.9f));
	if (ImGui::Button("搜索雷达", ImVec2(120, 0)))
	{
		// 发布搜索雷达事件
		EventManager::getInstance()->EventPublish(EventType::E_GUI_LIDAR_BROADCAST, std::make_shared<E_GUI_LIDAR_BROADCAST>());
	}

	ImGui::SetCursorPosX((windowWidth - closeButtonWidth) * 0.6666f);
	ImGui::SetCursorPosY((windowHeight * 0.9f));
	if (ImGui::Button("关闭", ImVec2(120, 0))) { ImGui::CloseCurrentPopup(); }

I added the listener in the main thread as well, which is in a constructor of another class.

GUITest::GUITest()
{
	std::shared_ptr<EventManager> eventManager = EventManager::getInstance();
	// 订阅雷达广播事件事件
	eventManager->EventSubscribe(EventType::E_GUI_LIDAR_BROADCAST, 
		std::bind(&GUITest::LidarBroadcastTest, this, std::placeholders::_1));
}

I've tried to add listener in the event processing thread and everything works well.

from eventpp.

RWBYBING avatar RWBYBING commented on August 15, 2024

I figured it out, it just a little typo in other part of my code. Really sorry for wasting your time!!!

And really appreciate your work!

from eventpp.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.