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