Sound Bakery  v0.1.0
Open-source audio middleware for games
Loading...
Searching...
No Matches
node_instance.h
1#pragma once
2
3#include "sound_bakery/core/core_include.h"
4
5#include "sound_bakery/node/container/sequence_container.h"
6
7#include <boost/msm/back/state_machine.hpp>
8#include <boost/msm/front/state_machine_def.hpp>
9#include <boost/msm/front/functor_row.hpp>
10#include <boost/msm/front/euml/common.hpp>
11#include <boost/msm/front/euml/operator.hpp>
12#include <boost/msm/front/euml/state_grammar.hpp>
13
14namespace sbk::engine
15{
16 class node_instance;
17 class game_object;
18
22 struct SB_CLASS node_group_instance
23 {
24 sc_dsp* lowpass = nullptr;
25 sc_dsp* highpass = nullptr;
26 std::unique_ptr<sc_node_group, SC_NODE_GROUP_DELETER> nodeGroup;
27 };
28
29 enum class node_instance_type
30 {
31 child,
32 bus,
33 main
34 };
35
37 {
39 node_instance_type type = node_instance_type::main;
40 node_instance* parentForChildren = nullptr;
41 sbk::engine::game_object* m_owningGameObject = nullptr;
42 };
44 {
45 };
47 {
48 };
50 {
51 float stopTime = 0.0f;
52 };
54 {
55 };
57 {
58 };
60 {
61 float deltaTime = 0.0f;
62 };
63
64 struct flag_playing{};
65 struct flag_stopped{};
66
67 struct SB_CLASS node_instance_fsm : public boost::msm::front::state_machine_def<node_instance_fsm>
68 {
70
71 struct state_uninit : public boost::msm::front::state<>{};
72 struct state_init : public boost::msm::front::state<>{};
73 struct state_playing : public boost::msm::front::state<>
74 {
75 typedef boost::mpl::vector1<flag_playing> flag_list;
76 };
77 struct state_virtual : public boost::msm::front::state<>
78 {
79 typedef boost::mpl::vector1<flag_playing> flag_list;
80 };
81 struct state_stopped : public boost::msm::front::state<>
82 {
83 typedef boost::mpl::vector1<flag_stopped> flag_list;
84 };
85
86 auto action_init(const event_init& init) -> void;
87 auto action_play(const event_play& play) -> void;
88 auto action_pause(const event_pause& pause) -> void;
89 auto action_stop(const event_stop& stop) -> void;
90 auto action_virtualise(const event_virtualise& virtualise) -> void;
91 auto action_devirtualise(const event_devirtualise& devirtualise) -> void;
92 struct SB_CLASS action_update
93 {
94 template <class event_class, class state_machine_class, class source_state_class, class target_state_class>
95 void operator()(event_class const& update, state_machine_class& stateMachine, source_state_class&, target_state_class&)
96 {
97 if (stateMachine.m_soundInstance)
98 {
99 if (ma_sound_at_end(&stateMachine.m_soundInstance->sound) == MA_TRUE)
100 {
101 stateMachine.process_event(event_stop());
102 }
103 }
104 else if (!stateMachine.m_children.empty())
105 {
106 unsigned int stoppedChildren = 0;
107
108 for (const auto& child : stateMachine.m_children)
109 {
110 child->update();
111
112 if (!child->is_playing())
113 {
114 ++stoppedChildren;
115 }
116 }
117
118 const bool allChildrenHaveStopped = stoppedChildren == stateMachine.m_children.size();
119
120 if (allChildrenHaveStopped)
121 {
122 // Sequence nodes retrigger when the current sound stops
123 if (stateMachine.m_referencingNode->get_object_type() == rttr::type::get<sbk::engine::sequence_container>())
124 {
125 stateMachine.m_children.clear();
126 ++stateMachine.m_numTimesPlayed;
127 stateMachine.init_child();
128
129 stateMachine.process_event(event_play());
130 }
131 else
132 {
133 stateMachine.process_event(event_stop());
134 }
135 }
136 }
137 }
138 };
139
140 auto guard_init(const event_init& init) -> bool;
141
142 typedef state_uninit initial_state; // the initial state of the player SM
143
144 struct transition_table : boost::mpl::vector
145 <
146 // Start, Event, Next, Action, Guard
147 row<state_uninit, event_init, state_init, &node_instance_fsm::action_init, &node_instance_fsm::guard_init>,
148 a_row<state_init, event_play, state_playing, &node_instance_fsm::action_play>,
149 a_row<state_playing, event_stop, state_stopped, &node_instance_fsm::action_stop>,
150 a_row<state_playing, event_virtualise, state_virtual, &node_instance_fsm::action_virtualise>,
151 a_row<state_virtual, event_devirtualise, state_playing, &node_instance_fsm::action_devirtualise>,
152 boost::msm::front::Row<state_playing, event_update, boost::msm::front::none, action_update, boost::msm::front::none>
153 >
154 {};
155
156 void init_parent();
157 void init_child();
158 auto init_node_group(const event_init& init) -> sb_result;
159 void init_callbacks();
160
161 static auto add_dsp_to_node_group(sc_node_group* nodeGroup, sc_dsp** dsp, const sc_dsp_config& config) -> sb_result;
162
163 auto set_volume(float oldVolume, float newVolume) -> void;
164 auto set_pitch(float oldPitch, float newPitch) -> void;
165 auto set_lowpass(float oldLowpass, float newLowpass) -> void;
166 auto set_highpass(float oldHighpass, float newHighpass) -> void;
167
168 std::shared_ptr<node> m_referencingNode;
169 class sbk::engine::node_instance* m_owner = nullptr;
170 sbk::engine::game_object* m_gameObject = nullptr;
171 node_group_instance m_nodeGroup;
172 std::shared_ptr<node_instance> m_parent;
173 std::vector<std::shared_ptr<node_instance>> m_children;
174 std::unique_ptr<sc_sound_instance, SC_SOUND_INSTANCE_DELETER> m_soundInstance;
175 unsigned int m_numTimesPlayed = 0;
176 };
177
182 class SB_CLASS node_instance : public sbk::core::object, public boost::msm::front::state_machine_def<node_instance>
183 {
184 REGISTER_REFLECTION(node_instance, sbk::core::object)
185
186 public:
187 auto init(const event_init& init) -> sb_result;
188 auto play() -> sb_result;
189 auto stop(float fadeTime = 0.0f) -> sb_result;
190 auto update() -> sb_result;
191
192 auto is_playing() const -> bool;
193 auto is_stopped() const -> bool;
194
195 auto get_referencing_node() const noexcept -> std::shared_ptr<node>;
196 auto get_parent() const noexcept -> node_instance*;
197 auto get_bus() const noexcept -> sc_node_group*;
198
199 private:
200 boost::msm::back::state_machine<node_instance_fsm> m_stateMachine;
201 };
202} // namespace sbk::engine
Definition database_ptr.h:23
Base object that all sound Bakery objects should inherit from.
Definition object.h:23
Definition bus.h:10
Definition gameobject.h:14
NodeInstances represent runtime versions of Nodes, either containers or busses.
Definition node_instance.h:183
Definition node_instance.h:57
Definition node_instance.h:37
Definition node_instance.h:47
Definition node_instance.h:44
Definition node_instance.h:50
Definition node_instance.h:60
Definition node_instance.h:54
Definition node_instance.h:64
Definition node_instance.h:65
Owns a node group and applies DSP effects to it.
Definition node_instance.h:23
Definition node_instance.h:72
Definition node_instance.h:68
Definition sound_chef_common.h:168
ma_node with an additional enum descriptor.
Definition sound_chef_common.h:181
Groups nodes/DSPs together into one.
Definition sound_chef_common.h:208