implemented hooks

This commit is contained in:
Felix Brendel
2020-02-29 23:41:13 +01:00
parent 8b50444d9e
commit f82af0b6be
4 changed files with 101 additions and 23 deletions
+1
View File
@@ -1,3 +1,4 @@
/bin/* /bin/*
*.report *.report
/ftb /ftb
vgcore.*
Regular → Executable
View File
+84
View File
@@ -0,0 +1,84 @@
#pragma once
#include "./arraylist.hpp"
// For std::decay
#include <type_traits>
template<typename>
struct TransientFunction; // intentionally not defined
template<typename R, typename ...Args>
struct TransientFunction<R(Args...)>
{
using Dispatcher = R(*)(void*, Args...);
Dispatcher m_Dispatcher; // A pointer to the static function that will call the
// wrapped invokable object
void* m_Target; // A pointer to the invokable object
// Dispatch() is instantiated by the TransientFunction constructor,
// which will store a pointer to the function in m_Dispatcher.
template<typename S>
static R Dispatch(void* target, Args... args)
{
return (*(S*)target)(args...);
}
template<typename T>
TransientFunction(T&& target)
: m_Dispatcher(&Dispatch<typename std::decay<T>::type>)
, m_Target(&target)
{
}
// Specialize for reference-to-function, to ensure that a valid pointer is
// stored.
using TargetFunctionRef = R(Args...);
TransientFunction(TargetFunctionRef target)
: m_Dispatcher(Dispatch<TargetFunctionRef>)
{
static_assert(sizeof(void*) == sizeof target,
"It will not be possible to pass functions by reference on this platform. "
"Please use explicit function pointers i.e. foo(target) -> foo(&target)");
m_Target = (void*)target;
}
R operator()(Args... args) const
{
return m_Dispatcher(m_Target, args...);
}
};
struct Hook : Array_List<TransientFunction<void()>> {
Hook() {
alloc();
}
~Hook () {
dealloc();
}
void operator<<(TransientFunction<void()> f) {
// FIXME(Felix): Why can I not call Array_List::append here??? Hallo?
if (next_index == length) {
length *= 2;
data = (TransientFunction<void()>*)realloc(data, length * sizeof(TransientFunction<void()>));
}
data[next_index] = f;
next_index++;
}
void operator()() {
while(next_index --> 0) {
fflush(stdout);
data[next_index]();
}
next_index = 0;
}
};
struct __System_Shutdown_Hook : Hook {
void operator()() = delete;
~__System_Shutdown_Hook() {
Hook::operator()();
dealloc();
}
} system_shutdown_hook;
+16 -23
View File
@@ -1,33 +1,26 @@
#define _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS
#include <stdio.h> #include <stdio.h>
#include "bucket_allocator.hpp" #include "./hooks.hpp"
Hook h;
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
Bucket_Allocator<int> ba(2, 1); printf("Hello world");
system_shutdown_hook << [] {
printf("Goodbye world\n");
};
int* a = ba.allocate(); h << []{
*a = 1; printf("Hallo1");
ba.free_object(a); };
h << [] {
printf("Hallo2");
};
int* b = ba.allocate(); h << [] {
*b = 2; printf("Hallo3");
};
int* c = ba.allocate(); h();
*c = 3;
int* d = ba.allocate();
*d = 4;
int* e = ba.allocate();
*e = 5;
int* f = ba.allocate();
*f = 6;
ba.for_each([](int* i){
printf("%d\n", *i);
});
return 0; return 0;
} }