Created
June 2, 2017 08:33
-
-
Save anonymous/4f952321467baaa11ee866a073313836 to your computer and use it in GitHub Desktop.
Avoiding dynamic memory allocation by using an internal buffer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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