Files
fs2open.github.com/code/utils/event.h
T
asarium 9651e7dca6 Add more generic scripting callback system
The current scripting hook is pretty simple and straight forward but it
makes a couple of scripting applications harder to implement than
needed.

For example, a lot of scripts need to do some work every frame
for all or some objects. The script needs to manage an internal list of
all the objects that are affected by that list which includes removing
invalid objects to conserve resources. This effectively mirrors what the
engine already does and adds unnecessary overhead.

In these changes I added a generic event system which can be used by any
part of the code for providing callbacks when a specific event occurs.
As an example, I added hooks for the pre- and post-move events to the
object class which are called before and after physics are applied to an
object.

I integrated that feature into the scripting system so now a script can
simply register a function as a callback which will be called whenever
the target event is executed.
2018-07-02 22:56:45 +02:00

48 lines
1.0 KiB
C++

#pragma once
#include "globalincs/pstypes.h"
#include <functional>
namespace util {
template <typename Ret, typename... Args>
class event final {
public:
using callback_type = std::function<Ret(Args...)>;
event() = default;
~event() = default;
void add(callback_type func) { _listeners.push_back(func); }
void clear() { _listeners.clear(); }
// This variant is used if the listeners return no values
template <typename Dummy = void>
inline typename std::enable_if<std::is_same<Ret, void>::value, Dummy>::type operator()(Args... args) const
{
for (const auto& l : _listeners) {
l(args...);
}
}
// In this case we collect the return values and return them to the caller
template <typename Dummy = SCP_vector<Ret>>
inline typename std::enable_if<!std::is_same<Ret, void>::value, Dummy>::type operator()(Args... args) const
{
SCP_vector<Ret> vals;
for (const auto& l : _listeners) {
vals.push_back(l(args...));
}
return vals;
}
private:
SCP_vector<callback_type> _listeners;
};
} // namespace util