25 #include <type_traits>
27 #include "../logging.h"
29 #include "../generic/property.h"
30 #include "../generic/managed.h"
31 #include "../interfaces/updateable.h"
32 #include "../input/input_manager.h"
41 typedef std::shared_ptr<Behaviour> BehaviourPtr;
48 virtual const char* name()
const = 0;
53 void _update_thunk(
float dt)
override;
54 void _late_update_thunk(
float dt)
override;
55 void _fixed_update_thunk(
float step)
override;
58 this, &Behaviour::organism_
61 bool attached()
const {
return organism_ !=
nullptr; }
66 void set_organism(
Organism* organism) {
69 on_behaviour_removed(organism_);
74 on_behaviour_added(organism);
75 }
else if(organism_) {
78 on_behaviour_removed(organism_);
83 virtual void on_behaviour_added(
Organism* controllable) {
84 _S_UNUSED(controllable);
87 virtual void on_behaviour_removed(
Organism* controllable) {
88 _S_UNUSED(controllable);
92 virtual void on_behaviour_first_update(
Organism* controllable) {
93 _S_UNUSED(controllable);
96 bool is_enabled_ =
true;
97 bool first_update_done_ =
false;
107 this, &BehaviourWithInput::input_
118 material_(material) {
125 Property<decltype(&MaterialBehaviour::material_)> material = {
126 this, &MaterialBehaviour::material_
128 Material* get_material()
const {
return material_; }
137 bool has_behaviour()
const {
138 return behaviour_types_.count(
typeid(T).hash_code()) > 0;
142 T* behaviour()
const {
143 auto hash_code =
typeid(T).hash_code();
144 if(!behaviour_types_.count(hash_code)) {
148 return dynamic_cast<T*
>(behaviour_types_.at(hash_code).get());
153 static_assert(std::is_base_of<Behaviour, T>::value,
"Behaviours must derive smlt::Behaviour");
154 static_assert(std::is_base_of<
RefCounted<T>, T>::value,
"Behaviours must derive RefCounted<T>");
155 std::shared_ptr<T> ret = T::create();
156 add_behaviour<T>(ret);
160 template<
typename T,
typename ...Params>
161 T* new_behaviour(Params&&... params) {
162 static_assert(std::is_base_of<Behaviour, T>::value,
"Behaviours must derive smlt::Behaviour");
163 static_assert(std::is_base_of<
RefCounted<T>, T>::value,
"Behaviours must derive RefCounted<T>");
164 std::shared_ptr<T> ret = T::create(std::forward<Params>(params)...);
165 add_behaviour<T>(ret);
169 void fixed_update_behaviours(
float step) {
170 for(
auto& behaviour: behaviours_) {
171 behaviour->_fixed_update_thunk(step);
175 void update_behaviours(
float dt) {
176 for(
auto& behaviour: behaviours_) {
179 if(!behaviour->first_update_done_) {
180 behaviour->on_behaviour_first_update(
this);
181 behaviour->first_update_done_ =
true;
184 behaviour->_update_thunk(dt);
188 void late_update_behaviours(
float dt) {
189 for(
auto& behaviour: behaviours_) {
190 behaviour->_late_update_thunk(dt);
196 void add_behaviour(std::shared_ptr<T> behaviour) {
197 static_assert(std::is_base_of<Behaviour, T>::value,
"Behaviours must derive smlt::Behaviour");
200 S_WARN(
"Tried to add a null behaviour to the controllable");
205 if(behaviour_names_.count(behaviour->name())) {
206 S_WARN(
"Tried to add a duplicate behaviour: {0}", (std::string)behaviour->name());
210 behaviour_types_.insert(std::make_pair(
typeid(T).hash_code(), behaviour));
211 behaviour_names_.insert(behaviour->name());
212 behaviours_.push_back(behaviour);
217 behaviour->set_organism(
this);
220 std::vector<BehaviourPtr> behaviours_;
221 std::unordered_set<std::string> behaviour_names_;
222 std::unordered_map<std::size_t, BehaviourPtr> behaviour_types_;
228 #endif // behaviour_H