Skip to content

Commit 83fcc6a

Browse files
authored
Merge pull request #74 from YGNI-RType/dev
Release v0.4.1
2 parents fc49e0d + 24eb8de commit 83fcc6a

File tree

9 files changed

+253
-131
lines changed

9 files changed

+253
-131
lines changed

include/GEngine/GEngine.hpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ class GEngine {
116116
* It also registers the necessary game engine elements by calling the registerElements method.
117117
*/
118118
static void init(int size, const char **argv) {
119+
getArgsSize(size);
120+
getArgs(argv);
119121
std::call_once(initFlag, [size, argv]() {
120122
instance.reset(new GEngine());
121123
instance->getLocal().setParams(argv, size);
@@ -172,6 +174,22 @@ class GEngine {
172174
return instance->m_remote;
173175
}
174176

177+
static size_t getArgsSize(size_t argsSize) {
178+
static size_t _argsSize = 0;
179+
180+
if (argsSize)
181+
_argsSize = argsSize;
182+
return _argsSize;
183+
}
184+
185+
static const char **getArgs(const char **args) {
186+
static const char **_args = NULL;
187+
188+
if (args)
189+
_args = args;
190+
return _args;
191+
}
192+
175193
private:
176194
/**
177195
* @brief Private constructor to prevent direct instantiation.
@@ -213,3 +231,6 @@ class GEngine {
213231
// Initialize static members
214232
// std::unique_ptr<GEngine> GEngine::instance = nullptr;
215233
// std::once_flag GEngine::initFlag;
234+
235+
#define GENGINE_ARGS_SIZE GEngine::getArgsSize(0)
236+
#define GENGINE_ARGS GEngine::getArgs(NULL)

include/GEngine/libdev/Systems.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@ using MotionAcceleration3D = gengine::system::MotionAcceleration3D;
3636
#include "GEngine/libdev/systems/driver/input/KeyboardCatcher.hpp"
3737
#include "GEngine/libdev/systems/driver/input/MouseCatcher.hpp"
3838
#include "GEngine/libdev/systems/driver/output/Animate.hpp"
39+
#include "GEngine/libdev/systems/driver/output/AudioManager.hpp"
3940
#include "GEngine/libdev/systems/driver/output/Draw.hpp"
4041
#include "GEngine/libdev/systems/driver/output/FontManager.hpp"
4142
#include "GEngine/libdev/systems/driver/output/RenderWindow.hpp"
42-
#include "GEngine/libdev/systems/driver/output/SoundManager.hpp"
4343
#include "GEngine/libdev/systems/driver/output/TextureManager.hpp"
4444

4545
namespace geg::system::io {
@@ -60,7 +60,7 @@ using FontManager = gengine::system::driver::output::FontManager;
6060

6161
using RenderWindow = gengine::system::driver::output::RenderWindow;
6262

63-
using SoundManager = gengine::system::driver::output::SoundManager;
63+
using AudioManager = gengine::system::driver::output::AudioManager;
6464

6565
using TextureManager = gengine::system::driver::output::TextureManager;
6666
}; // namespace geg::system::io

include/GEngine/libdev/components/driver/output/Sound.hpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,20 @@
1616
namespace gengine::component::driver::output {
1717
struct Sound : public gengine::Component<Sound> {
1818
std::uint64_t soundId;
19-
std::uint64_t _ack = 0;
2019

2120
Sound(std::uint64_t soundId)
2221
: soundId(soundId) {
2322
}
2423
};
24+
25+
struct Music : public gengine::Component<Music> {
26+
bool pause = false;
27+
std::uint64_t musicId;
28+
29+
Music(std::uint64_t musicId)
30+
: musicId(musicId) {
31+
}
32+
33+
bool operator==(const Music &) const = default;
34+
};
2535
} // namespace gengine::component::driver::output

include/GEngine/libdev/systems/MainLoop.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <chrono>
2020

2121
#include "GEngine/libdev/System.hpp"
22+
#include "GEngine/libdev/systems/events/CLI.hpp"
2223
#include "GEngine/libdev/systems/events/MainLoop.hpp"
2324
#include "GEngine/libdev/systems/events/Native.hpp"
2425

@@ -35,6 +36,8 @@ class AutoMainLoop : public gengine::System<AutoMainLoop> {
3536

3637
void onStopMainLoop(gengine::system::event::StopMainLoop &e);
3738

39+
void onExit(gengine::system::event::CLINewInput &e);
40+
3841
std::chrono::microseconds getElapsedTime(void);
3942

4043
private:

include/GEngine/libdev/systems/driver/output/SoundManager.hpp renamed to include/GEngine/libdev/systems/driver/output/AudioManager.hpp

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
** ════════════════════════════════════════════════════════════════════════════
33
** GEngine (libdev) System
44
** ════════════════════════════════════════════════════════════════════════════
5-
** File : SoundManager.hpp
5+
** File : AudioManager.hpp
66
** Create at : 2024-10-15 05:02
77
** Author : AUTHOR
88
** Description : This system dedicated to ther DriverEngine, it must with
@@ -32,10 +32,12 @@
3232

3333
namespace gengine::system::driver::output {
3434

35-
class SoundManager : public gengine::System<SoundManager, gengine::component::driver::output::Sound,
36-
gengine::interface::component::RemoteLocal> {
35+
class AudioManager
36+
: public gengine::System<AudioManager, gengine::component::driver::output::Sound,
37+
gengine::component::driver::output::Music, gengine::interface::component::RemoteLocal,
38+
geg::component::network::NetSend> {
3739
public:
38-
SoundManager(const std::string &folder);
40+
AudioManager(const std::string &soundFolder, const std::string &musicFolder);
3941
virtual void init(void) override {
4042
}
4143

@@ -51,27 +53,58 @@ class SoundManager : public gengine::System<SoundManager, gengine::component::dr
5153

5254
void onMainLoop(geg::event::MainLoop &e);
5355
void onSoundPlayed(gengine::interface::event::SharedEvent<gengine::system::event::driver::output::SoundPlayed> &e);
56+
void onMusic(gengine::system::event::driver::output::Music &e) {
57+
auto &musics = getComponents<gengine::component::driver::output::Music>();
58+
auto &netSends = getComponents<geg::component::network::NetSend>();
59+
60+
if (!musics.size())
61+
spawnEntity(gengine::component::driver::output::Music(getMusicIdByPath(e.path)),
62+
geg::component::network::NetSend());
63+
else {
64+
getMusicComponent().musicId = getMusicIdByPath(e.path);
65+
for (auto [e, _unused, netSend] : gengine::Zip(musics, netSends)) {
66+
netSend.update();
67+
break;
68+
}
69+
}
70+
std::cout << "music: " << getMusicComponent().musicId << std::endl;
71+
}
5472

5573
protected:
74+
const std::string m_soundFolder;
75+
const std::string m_musicFolder;
5676
std::string m_folder;
5777
std::unordered_map<std::string, std::pair<std::uint64_t, Sound>> m_soundTable;
58-
std::uint64_t m_baseId = 0;
78+
std::unordered_map<std::string, std::pair<std::uint64_t, Music>> m_musicTable;
79+
std::uint64_t m_soundBaseId = 0;
80+
std::uint64_t m_musicBaseId = 1;
81+
std::uint64_t m_currentMusicId = 0;
5982

6083
std::uint64_t getIdByPath(const std::string &path) const;
84+
Music getMusicById(std::uint64_t id);
85+
std::uint64_t getMusicIdByPath(const std::string &path) {
86+
auto it = m_musicTable.find(path);
87+
88+
if (it == m_musicTable.end())
89+
THROW_WARNING("Music not found");
6190

91+
return it->second.first;
92+
}
6293
void playSoundById(std::uint64_t id);
94+
95+
gengine::component::driver::output::Music &getMusicComponent(void);
6396
};
6497

65-
class SoundManagerLocal : public SoundManager, public gengine::LocalSystem {
98+
class AudioManagerLocal : public AudioManager, public gengine::LocalSystem {
6699
public:
67-
SoundManagerLocal(const std::string &folder);
100+
AudioManagerLocal(const std::string &soundFolder, const std::string &musicFolder);
68101

69102
void init(void) override;
70103
};
71104

72-
class SoundManagerRemote : public SoundManager, public gengine::RemoteSystem {
105+
class AudioManagerRemote : public AudioManager, public gengine::RemoteSystem {
73106
public:
74-
SoundManagerRemote(const std::string &folder);
107+
AudioManagerRemote(const std::string &soundFolder, const std::string &musicFolder);
75108

76109
void init(void) override;
77110
};

include/GEngine/libdev/systems/events/driver/output/Sound.hpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
** File : Sound.hpp
66
** Create at : 2024-10-15 05:14
77
** Author : AUTHOR
8-
** Description : This event is listened to natively by the SoundManager system
8+
** Description : This event is listened to natively by the AudioManager system
99
which will launch the sound linked to the path passed as an
1010
argument when it is triggered by this event.
1111
** ════════════════════════════════════════════════════════════════════════════
@@ -38,4 +38,12 @@ struct SoundPlayed : public Event {
3838
: soundId(soundId) {
3939
}
4040
};
41+
42+
struct Music : public Event {
43+
Music(const std::string &path)
44+
: path(path) {
45+
}
46+
47+
const std::string path;
48+
};
4149
} // namespace gengine::system::event::driver::output

source/GEngine/libdev/systems/MainLoop.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ void AutoMainLoop::init(void) {
3131
subscribeToEvent<gengine::system::event::StartEngine>(&AutoMainLoop::onStartEngine);
3232
subscribeToEvent<gengine::system::event::MainLoop>(&AutoMainLoop::onMainLoop);
3333
subscribeToEvent<gengine::system::event::StopMainLoop>(&AutoMainLoop::onStopMainLoop);
34+
subscribeToEvent<gengine::system::event::CLINewInput>(&AutoMainLoop::onExit);
35+
}
36+
37+
void AutoMainLoop::onExit(gengine::system::event::CLINewInput &e) {
38+
if (e.prompt.size() && !e.prompt[0].compare("exit"))
39+
m_isRunning = false;
3440
}
3541

3642
void AutoMainLoop::onStartEngine(gengine::system::event::StartEngine &e) {
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
/*
2+
** EPITECH PROJECT, 2024
3+
** GameEngine
4+
** File description:
5+
** AudioManager.cpp
6+
*/
7+
8+
#include "GEngine/libdev/systems/driver/output/AudioManager.hpp"
9+
10+
namespace gengine::system::driver::output {
11+
12+
AudioManager::AudioManager(const std::string &soundFolder, const std::string &musicFolder)
13+
: m_soundFolder(soundFolder)
14+
, m_musicFolder(musicFolder) {
15+
}
16+
17+
void AudioManager::onStartEngine(gengine::system::event::StartEngine &e) {
18+
SetTraceLogLevel(LOG_WARNING);
19+
InitAudioDevice();
20+
for (const auto &entry : std::filesystem::recursive_directory_iterator(m_soundFolder)) {
21+
if (entry.is_regular_file()) {
22+
std::string filePath = entry.path().string();
23+
24+
Sound sound = LoadSound(filePath.c_str());
25+
std::string path = std::filesystem::relative(entry.path(), m_soundFolder).string();
26+
m_soundTable.insert({path, {m_soundBaseId++, sound}});
27+
}
28+
}
29+
for (const auto &entry : std::filesystem::recursive_directory_iterator(m_musicFolder)) {
30+
if (entry.is_regular_file()) {
31+
std::string filePath = entry.path().string();
32+
33+
Music music = LoadMusicStream(filePath.c_str());
34+
std::string path = std::filesystem::relative(entry.path(), m_musicFolder).string();
35+
m_musicTable.insert({path, {m_musicBaseId++, music}});
36+
}
37+
}
38+
}
39+
40+
Music AudioManager::getMusicById(std::uint64_t id) {
41+
for (auto &[_, pair] : m_musicTable)
42+
if (pair.first == id)
43+
return pair.second;
44+
THROW_WARNING("Music component not initilized");
45+
}
46+
47+
void AudioManager::onStopEngine(gengine::system::event::StopEngine &e) {
48+
for (auto &[path, sound] : m_soundTable)
49+
UnloadSound(sound.second);
50+
}
51+
52+
const Sound &AudioManager::get(const std::string &path) {
53+
const auto &sound = m_soundTable.find(path);
54+
if (sound == m_soundTable.cend())
55+
THROW_ERROR("Out of range: This sound does not exist. PATH: " + path);
56+
57+
return sound->second.second;
58+
}
59+
60+
void AudioManager::onMainLoop(geg::event::MainLoop &e) {
61+
auto &sounds = getComponents<gengine::component::driver::output::Sound>();
62+
auto &musics = getComponents<gengine::component::driver::output::Music>();
63+
64+
if (musics.size()) {
65+
auto &music = getMusicComponent();
66+
if (music.musicId != m_currentMusicId) {
67+
if (m_currentMusicId)
68+
StopMusicStream(getMusicById(m_currentMusicId));
69+
m_currentMusicId = music.musicId;
70+
PlayMusicStream(getMusicById(m_currentMusicId));
71+
}
72+
}
73+
74+
if (m_currentMusicId)
75+
UpdateMusicStream(getMusicById(m_currentMusicId));
76+
77+
static std::set<gengine::Entity> m_soundsPlayed;
78+
79+
for (auto &[e, sound] : sounds) {
80+
if (m_soundsPlayed.find(e) == m_soundsPlayed.end()) {
81+
m_soundsPlayed.insert(e);
82+
playSoundById(sound.soundId);
83+
}
84+
publishEvent(gengine::system::event::driver::output::SoundPlayed(sound.soundId));
85+
}
86+
for (auto it = m_soundsPlayed.begin(); it != m_soundsPlayed.end();)
87+
if (!sounds.contains(*it))
88+
it = m_soundsPlayed.erase(it);
89+
else
90+
++it;
91+
}
92+
93+
gengine::component::driver::output::Music &AudioManager::getMusicComponent(void) {
94+
auto &musics = getComponents<gengine::component::driver::output::Music>();
95+
96+
if (!musics.size())
97+
THROW_WARNING("Music component not initilazed");
98+
for (auto &[_, m] : musics)
99+
return m;
100+
}
101+
102+
void AudioManager::onSoundPlayed(
103+
gengine::interface::event::SharedEvent<gengine::system::event::driver::output::SoundPlayed> &e) {
104+
static std::unordered_map<std::uint64_t, std::set<uuids::uuid>> m_soundsAck;
105+
auto &remoteLocals = getComponents<gengine::interface::component::RemoteLocal>();
106+
auto &sounds = getComponents<gengine::component::driver::output::Sound>();
107+
108+
if (m_soundsAck.find(e->soundId) == m_soundsAck.end())
109+
m_soundsAck.insert({e->soundId, std::set<uuids::uuid>()});
110+
m_soundsAck[e->soundId].insert(e.remoteUUID);
111+
112+
for (auto &[entity, s] : sounds) {
113+
if (s.soundId == e->soundId && m_soundsAck[e->soundId].size() == remoteLocals.size())
114+
killEntity(entity);
115+
m_soundsAck.erase(e->soundId);
116+
}
117+
}
118+
119+
std::uint64_t AudioManager::getIdByPath(const std::string &path) const {
120+
auto it = m_soundTable.find(path);
121+
122+
if (it == m_soundTable.end())
123+
THROW_WARNING("Sound not found");
124+
125+
return it->second.first;
126+
}
127+
128+
void AudioManager::playSoundById(std::uint64_t id) {
129+
for (auto &[_, pair] : m_soundTable) {
130+
if (pair.first == id) {
131+
PlaySound(pair.second);
132+
return;
133+
}
134+
}
135+
}
136+
137+
AudioManagerLocal::AudioManagerLocal(const std::string &soundFolder, const std::string &musicFolder)
138+
: AudioManager(soundFolder, musicFolder) {
139+
}
140+
141+
void AudioManagerLocal::init(void) {
142+
subscribeToEvent<gengine::system::event::StartEngine>(&AudioManager::onStartEngine);
143+
subscribeToEvent<gengine::system::event::StopEngine>(&AudioManager::onStopEngine);
144+
subscribeToEvent<geg::event::MainLoop>(&AudioManager::onMainLoop);
145+
}
146+
147+
AudioManagerRemote::AudioManagerRemote(const std::string &soundFolder, const std::string &musicFolder)
148+
: AudioManager(soundFolder, musicFolder) {
149+
}
150+
151+
void AudioManagerRemote::init(void) {
152+
subscribeToEvent<gengine::system::event::StartEngine>(&AudioManager::onStartEngine);
153+
subscribeToEvent<gengine::system::event::StopEngine>(&AudioManager::onStopEngine);
154+
subscribeToEvent<gengine::system::event::driver::output::Sound>(&AudioManager::onSound);
155+
subscribeToEvent<gengine::interface::event::SharedEvent<gengine::system::event::driver::output::SoundPlayed>>(
156+
&AudioManager::onSoundPlayed);
157+
subscribeToEvent<gengine::system::event::driver::output::Music>(&AudioManager::onMusic);
158+
}
159+
} // namespace gengine::system::driver::output

0 commit comments

Comments
 (0)