Skip to content

Instantly share code, notes, and snippets.

Created June 2, 2017 08:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/4f952321467baaa11ee866a073313836 to your computer and use it in GitHub Desktop.
Save anonymous/4f952321467baaa11ee866a073313836 to your computer and use it in GitHub Desktop.
Avoiding dynamic memory allocation by using an internal buffer
class InputController
{
class InputValidator
{
public:
virtual bool Invoke() const = 0;
virtual ~InputValidator(void) {}
};
template <typename Device, typename Function, typename Button>
class InputValidatorWrapper : public InputValidator
{
public:
InputValidatorWrapper(Device * device, Function function, Button button)
: m_device(device)
, m_function(function)
, m_button(button)
{}
virtual bool Invoke() const { return (m_device->*m_function)(m_button); };
private:
Device* m_device;
Function m_function;
Button m_button;
};
struct InputStorage
{
// NOTE: this needs to be large enough to hold any InputValidatorWrapper of any type.
// pointers-to-member-functions can have different sizes depending on where they point to (compiler-dependent).
static const size_t MAX_SIZE = 16u;
InputValidator* validator;
char memory[MAX_SIZE];
};
public:
InputController(void)
: m_index(0u)
{
}
~InputController(void)
{
for (size_t i = 0u; i < m_index; ++i)
{
InputValidator* validator = m_storage[i].validator;
validator->~InputValidator();
}
}
template <typename Device, typename Function, typename Button>
void AddInput(Device* device, Function funct, Button button)
{
typedef InputValidatorWrapper<Device, Function, Button> Wrapper;
// make sure that this type of wrapper really fits into the storage buffer
static_assert(sizeof(Wrapper) <= InputStorage::MAX_SIZE, "Buffer is too small.");
void* memory = m_storage[m_index].memory;
m_storage[m_index].validator = new (memory) Wrapper(device, funct, button);
++m_index;
}
bool IsAnyTriggered()
{
bool result = false;
for (size_t i = 0u; i < m_index; ++i)
{
result |= m_storage[i].validator->Invoke();
}
return result;
}
private:
static const size_t MAX_INPUTS = 16;
InputStorage m_storage[MAX_INPUTS];
size_t m_index;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment