parent
b687946251
commit
17acf0a45a
12 changed files with 285 additions and 7 deletions
@ -1,6 +0,0 @@ |
||||
#include <iostream> |
||||
|
||||
int main() { |
||||
std::cout << "Hello, World!" << std::endl; |
||||
return 0; |
||||
} |
@ -0,0 +1,16 @@ |
||||
#include "Audio.h" |
||||
|
||||
#include <iostream> |
||||
|
||||
void Audio::update() { |
||||
auto cmd = pop(); |
||||
|
||||
// use volume, soundId to play sound
|
||||
|
||||
delete cmd; |
||||
} |
||||
|
||||
void Audio::playSound(double volume, unsigned int soundId) { |
||||
auto command = new AudioCommand {volume, soundId}; |
||||
push(command); |
||||
} |
@ -0,0 +1,14 @@ |
||||
#pragma once |
||||
|
||||
#include "Queue.h" |
||||
|
||||
struct AudioCommand { |
||||
double volume; |
||||
unsigned soundId; |
||||
}; |
||||
|
||||
class Audio : private Queue<AudioCommand> { |
||||
void update() override; |
||||
public: |
||||
void playSound(double volume, unsigned soundId); |
||||
}; |
@ -0,0 +1,21 @@ |
||||
#pragma once |
||||
|
||||
#include <string> |
||||
#include <QEvent> |
||||
|
||||
struct InputEvent{ |
||||
QEvent::Type type; |
||||
}; |
||||
|
||||
struct GameEvent { |
||||
int time = 0; |
||||
virtual void print() {}; |
||||
}; |
||||
|
||||
struct CoinCollectEvent : GameEvent { |
||||
double value = 0; |
||||
}; |
||||
|
||||
struct DamageEvent : GameEvent { |
||||
double amount = 0; |
||||
}; |
@ -0,0 +1,30 @@ |
||||
#include "FileManager.h" |
||||
#include <iostream> |
||||
|
||||
void FileManager::update() { |
||||
auto cmd = pop(); |
||||
cmd->execute(); |
||||
delete cmd; |
||||
} |
||||
|
||||
void FileManager::readFile(const std::string &path, const std::function<void(std::string)> &readCallback) { |
||||
auto cmd = new FileReadCommand; |
||||
cmd->path = path; |
||||
cmd->readCallback = readCallback; |
||||
push(cmd); |
||||
} |
||||
|
||||
void FileManager::writeFile(const std::string &path, const std::string &content) { |
||||
auto cmd = new FileWriteCommand; |
||||
cmd->path = path; |
||||
cmd->content = content; |
||||
push(cmd); |
||||
} |
||||
|
||||
void FileReadCommand::execute() { |
||||
|
||||
} |
||||
|
||||
void FileWriteCommand::execute() { |
||||
|
||||
} |
@ -0,0 +1,25 @@ |
||||
#pragma once |
||||
|
||||
#include "Queue.h" |
||||
|
||||
struct FileCommand { |
||||
std::string path; |
||||
virtual void execute() {}; |
||||
}; |
||||
|
||||
struct FileReadCommand : FileCommand { |
||||
std::function<void(std::string)> readCallback; |
||||
void execute() override; |
||||
}; |
||||
|
||||
struct FileWriteCommand : FileCommand { |
||||
std::string content; |
||||
void execute() override; |
||||
}; |
||||
|
||||
class FileManager : private Queue<FileCommand>{ |
||||
void update() override; |
||||
public: |
||||
void readFile(const std::string &path, const std::function<void(std::string)> &readCallback); |
||||
void writeFile(const std::string &path, const std::string &content); |
||||
}; |
@ -0,0 +1,17 @@ |
||||
#pragma once |
||||
|
||||
template <typename EventType> |
||||
class Listener { |
||||
protected: |
||||
template <typename T> |
||||
bool isType(EventType * event) { |
||||
return cast<T>(event); |
||||
} |
||||
template <typename T> |
||||
T * cast(EventType * event) { |
||||
return dynamic_cast<T *>(event); |
||||
} |
||||
public: |
||||
virtual bool wantsEvent(EventType *) { return true; } |
||||
virtual void accept(EventType *) {} |
||||
}; |
@ -0,0 +1,22 @@ |
||||
#include "Player.h" |
||||
#include <iostream> |
||||
|
||||
bool Player::wantsEvent(GameEvent * event) { |
||||
return isType<CoinCollectEvent>(event) || isType<DamageEvent>(event); |
||||
} |
||||
|
||||
void Player::accept(GameEvent *event) { |
||||
if (auto coinEvent = cast<CoinCollectEvent>(event)) |
||||
OnCoinCollect(coinEvent); |
||||
|
||||
if (auto dmgEvent = cast<DamageEvent>(event)) |
||||
OnDamage(dmgEvent); |
||||
} |
||||
|
||||
void Player::OnCoinCollect(CoinCollectEvent *event) { |
||||
std::cout << event->value << std::endl; |
||||
} |
||||
|
||||
void Player::OnDamage(DamageEvent *event) { |
||||
std::cout << event->amount << std::endl; |
||||
} |
@ -0,0 +1,13 @@ |
||||
#pragma once |
||||
|
||||
#include "Listener.h" |
||||
#include "Event.h" |
||||
|
||||
class Player : public Listener<GameEvent> { |
||||
public: |
||||
bool wantsEvent(GameEvent * event) override; |
||||
void accept(GameEvent * event) override; |
||||
protected: |
||||
void OnCoinCollect(CoinCollectEvent * event); |
||||
void OnDamage(DamageEvent * event); |
||||
}; |
@ -0,0 +1,74 @@ |
||||
#pragma once |
||||
|
||||
#include <vector> |
||||
|
||||
#include "Event.h" |
||||
#include "Listener.h" |
||||
#include <thread> |
||||
#include <QApplication> |
||||
#include <mutex> |
||||
|
||||
template<typename T> |
||||
class Queue { |
||||
private: |
||||
std::thread thread; |
||||
std::mutex mutex; |
||||
void run() { |
||||
while (!QApplication::closingDown()){ |
||||
if (!container.empty()) |
||||
update(); |
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1)); |
||||
} |
||||
}; |
||||
virtual void update() {} |
||||
std::vector<T *> container; |
||||
protected: |
||||
size_t size() const { |
||||
return container.size(); |
||||
} |
||||
T * pop(){ |
||||
mutex.lock(); |
||||
T * element = container.back(); |
||||
container.pop_back(); |
||||
mutex.unlock(); |
||||
return element; |
||||
} |
||||
public: |
||||
Queue(){ |
||||
thread = std::thread(&Queue::run, this); |
||||
} |
||||
void push(T * element){ |
||||
mutex.lock(); |
||||
container.insert(container.begin(), element); |
||||
mutex.unlock(); |
||||
} |
||||
}; |
||||
|
||||
|
||||
template <typename EventType> |
||||
class EventQueue : protected Queue<EventType>{ |
||||
std::vector<Listener<EventType> *> listeners; |
||||
void update() override { |
||||
EventType * event = this->pop(); |
||||
|
||||
for (auto listener : listeners) |
||||
if (listener->wantsEvent(event)) |
||||
listener->accept(event); |
||||
|
||||
delete event; |
||||
} |
||||
public: |
||||
template <typename T> |
||||
void submitEvent(T * event){ |
||||
this->push(event); |
||||
} |
||||
void registerListener(Listener<EventType> * listener){ |
||||
listeners.push_back(listener); |
||||
} |
||||
void unregisterListener(Listener<EventType> * listener){ |
||||
std::remove(listeners.begin(), listeners.end(), listener); |
||||
} |
||||
}; |
||||
|
||||
using InputQueue = EventQueue<InputEvent>; |
||||
using GameQueue = EventQueue<GameEvent>; |
@ -0,0 +1,43 @@ |
||||
#include <QApplication> |
||||
#include <QWidget> |
||||
#include <iostream> |
||||
#include "Queue.h" |
||||
#include "Audio.h" |
||||
#include "FileManager.h" |
||||
#include "Player.h" |
||||
|
||||
using std::cout, std::endl; |
||||
|
||||
auto audioManager = new Audio; |
||||
auto fileManager = new FileManager; |
||||
auto gameQueue = new GameQueue; |
||||
auto inputQueue = new InputQueue; |
||||
|
||||
int main(int argc, char * argv[]){ |
||||
QApplication app(argc, argv); |
||||
|
||||
/*
|
||||
for (int i = 0; i < 100'000; i++) |
||||
audioManager->playSound(1, i); |
||||
*/ |
||||
|
||||
/*
|
||||
for (int i = 0; i < 10'000; i++){ |
||||
fileManager->readFile("path" + std::to_string(i), [](const std::string& content){ |
||||
std::cout << content << std::endl; |
||||
}); |
||||
fileManager->writeFile("path" + std::to_string(i), "some content" + std::to_string(i)); |
||||
} |
||||
*/ |
||||
|
||||
auto player = new Player; |
||||
gameQueue->registerListener(player); |
||||
gameQueue->submitEvent<CoinCollectEvent>(new CoinCollectEvent); |
||||
gameQueue->submitEvent<DamageEvent>(new DamageEvent); |
||||
inputQueue->submitEvent<InputEvent>(new InputEvent); |
||||
|
||||
QWidget window; |
||||
window.show(); |
||||
|
||||
return QApplication::exec(); |
||||
} |
Loading…
Reference in new issue