You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

78 lines
2.0 KiB

  1. #pragma once
  2. #include "./arraylist.hpp"
  3. // For std::decay
  4. #include <type_traits>
  5. template<typename>
  6. struct Lambda; // intentionally not defined
  7. template<typename R, typename ...Args>
  8. struct Lambda<R(Args...)>
  9. {
  10. using Dispatcher = R(*)(void*, Args...);
  11. Dispatcher m_Dispatcher; // A pointer to the static function that will call the
  12. // wrapped invokable object
  13. void* m_Target; // A pointer to the invokable object
  14. // Dispatch() is instantiated by the Lambda constructor,
  15. // which will store a pointer to the function in m_Dispatcher.
  16. template<typename S>
  17. static R Dispatch(void* target, Args... args)
  18. {
  19. return (*(S*)target)(args...);
  20. }
  21. template<typename T>
  22. Lambda(T&& target)
  23. : m_Dispatcher(&Dispatch<typename std::decay<T>::type>)
  24. , m_Target(&target)
  25. {
  26. }
  27. // Specialize for reference-to-function, to ensure that a valid pointer is
  28. // stored.
  29. using TargetFunctionRef = R(Args...);
  30. Lambda(TargetFunctionRef target)
  31. : m_Dispatcher(Dispatch<TargetFunctionRef>)
  32. {
  33. static_assert(sizeof(void*) == sizeof target,
  34. "It will not be possible to pass functions by reference on this platform. "
  35. "Please use explicit function pointers i.e. foo(target) -> foo(&target)");
  36. m_Target = (void*)target;
  37. }
  38. R operator()(Args... args) const
  39. {
  40. return m_Dispatcher(m_Target, args...);
  41. }
  42. };
  43. struct Hook {
  44. Array_List<Lambda<void()>> lambdas;
  45. Hook() {
  46. lambdas.alloc();
  47. }
  48. ~Hook () {
  49. lambdas.dealloc();
  50. }
  51. void operator<<(Lambda<void()>&& f) {
  52. lambdas.append(f);
  53. }
  54. void operator()() {
  55. for (auto l : lambdas) {
  56. l();
  57. }
  58. lambdas.clear();
  59. }
  60. };
  61. // struct __System_Shutdown_Hook : Hook {
  62. // void operator()() = delete;
  63. // ~__System_Shutdown_Hook() {
  64. // Hook::operator()();
  65. // lambdas.dealloc();
  66. // }
  67. // } system_shutdown_hook;