/***- Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). Licensed under the Unlicense license // Public Domain File: AuroraInterfaces.hpp Date: 2021-6-10 Author: Reece Project: https://git.reece.sx/AuroraSupport/AuroraInterfaces, https://git.reece.sx/AuroraSupport/AuroraRuntime Note: Aurora Runtime will ship with its own implementation of this ***/ #pragma once #if defined(AURORA_RUNTIME_AU_FUNC) template using AuiFunction = AURORA_RUNTIME_AU_FUNC; #elif defined(AUI_FUNC) template using AuiFunction = AUI_FUNC; #else #include template using AuiFunction = std::function; #endif #define AUI_BRACKET_SCOPE(...) __VA_ARGS__ #define AUI_EXPAND_PARAMS_JOINER_A(a, b) a b #define AUI_EXPAND_PARAMS_JOINER_B(a, b) , a b #define AUI_EXPAND_PARAMS(...) AU_FOR_EACH_FIRST_2(AUI_EXPAND_PARAMS_JOINER_A, AUI_EXPAND_PARAMS_JOINER_B, __VA_ARGS__) #define AUI_EXPAND_PARAMS_TYPES_JOINER_A(a, b) a #define AUI_EXPAND_PARAMS_TYPES_JOINER_B(a, b) , a #define AUI_EXPAND_PARAMS_TYPES(...) AU_FOR_EACH_FIRST_2(AUI_EXPAND_PARAMS_TYPES_JOINER_A, AUI_EXPAND_PARAMS_TYPES_JOINER_B, __VA_ARGS__) #define AUI_EXPAND_PARAMS_PARAMS_JOINER_A(a, b) b #define AUI_EXPAND_PARAMS_PARAMS_JOINER_B(a, b) , b #define AUI_EXPAND_PARAMS_PARAMS(...) AU_FOR_EACH_FIRST_2(AUI_EXPAND_PARAMS_PARAMS_JOINER_A, AUI_EXPAND_PARAMS_PARAMS_JOINER_B, __VA_ARGS__) #define AUI_METHOD_IMPL(ret, name, params) virtual ret name(AUI_EXPAND_PARAMS params) = 0; #define AUI_METHOD_FUNCTIONAL_IMPL(ret, name, params) \ name ## _t name ## Functional; \ inline virtual ret name (AUI_EXPAND_PARAMS params) override \ { \ if (!name ## Functional) \ { \ return ret(); \ } \ return name ## Functional(AUI_EXPAND_PARAMS_PARAMS params); \ } #define AUI_METHOD_FUNCTIONAL_TYPEDEF(ret, name, params) \ using name ## _t = AuiFunction; #define AUI_METHOD_PROTOTYPE_TO_FUNCTIONAL(ret, name, params) \ name ## _t name ## Functional #define AUI_METHOD_PROTOTYPE_TO_FUNCTIONAL_CREF(ret, name, params) \ const name ## _t &name ## Functional #define AUI_METHOD_PROTOTYPE_TO_FUNCTIONAL_REF(ret, name, params) \ name ## _t && name ## Functional #define AUI_METHOD_FUNCTIONAL_CTOR_PARAMS_BASE_A(ret, name, params) AUI_METHOD_PROTOTYPE_TO_FUNCTIONAL_CREF(ret, name, params) #define AUI_METHOD_FUNCTIONAL_CTOR_PARAMS_BASE_B(ret, name, params) , AUI_METHOD_PROTOTYPE_TO_FUNCTIONAL_CREF(ret, name, params) #define AUI_METHOD_FUNCTIONAL_CTOR_PARAMS_REF_A(ret, name, params) AUI_METHOD_PROTOTYPE_TO_FUNCTIONAL_REF(ret, name, params) #define AUI_METHOD_FUNCTIONAL_CTOR_PARAMS_REF_B(ret, name, params) , AUI_METHOD_PROTOTYPE_TO_FUNCTIONAL_REF(ret, name, params) #define AUI_METHOD_PROTOTYPE_ASSIGN(ret, name, params) \ name ## Functional(name ## Functional) #define AUI_METHOD_FUNCTIONAL_ASSIGN_A(ret, name, params) : AUI_METHOD_PROTOTYPE_ASSIGN(ret, name, params) #define AUI_METHOD_FUNCTIONAL_ASSIGN_B(ret, name, params) , AUI_METHOD_PROTOTYPE_ASSIGN(ret, name, params) #define AUI_METHOD_FUNCTIONAL_FWD(ret, name, params) \ AUI_METHOD_PROTOTYPE_TO_FUNCTIONAL(ret, name, params); \ virtual ret name (AUI_EXPAND_PARAMS params) override; #define AUI_DEFINE_INTERFACE_START_STRUCT(name, ...) struct name \ { \ AU_FOR_EACH_3(AUI_METHOD_IMPL, __VA_ARGS__) \ }; #define AUI_DEFINE_INTERFACE_START_FUNCTIONAL_BASE(tmpl, name, ...) struct name ## Functional : name \ { \ AU_FOR_EACH_3(AUI_METHOD_FUNCTIONAL_TYPEDEF, __VA_ARGS__) \ inline name ## Functional () {} \ inline ~name ## Functional () {} \ inline name ## Functional (AU_FOR_EACH_FIRST_3(AUI_METHOD_FUNCTIONAL_CTOR_PARAMS_BASE_A, AUI_METHOD_FUNCTIONAL_CTOR_PARAMS_BASE_B, __VA_ARGS__)) \ AU_FOR_EACH_FIRST_3(AUI_METHOD_FUNCTIONAL_ASSIGN_A, AUI_METHOD_FUNCTIONAL_ASSIGN_B, __VA_ARGS__) \ {} \ inline name ## Functional (AU_FOR_EACH_FIRST_3(AUI_METHOD_FUNCTIONAL_CTOR_PARAMS_REF_A, AUI_METHOD_FUNCTIONAL_CTOR_PARAMS_REF_B, __VA_ARGS__)) \ AU_FOR_EACH_FIRST_3(AUI_METHOD_FUNCTIONAL_ASSIGN_A, AUI_METHOD_FUNCTIONAL_ASSIGN_B, __VA_ARGS__) \ {} \ AU_FOR_EACH_3(tmpl, __VA_ARGS__) \ }; #define AUI_DEFINE_INTERFACE_START_CPP_WRAPPER_FWD(name, ...) AUI_DEFINE_INTERFACE_START_FUNCTIONAL_BASE(AUI_METHOD_FUNCTIONAL_IMPL, name, __VA_ARGS__) #define AUI_DEFINE_INTERFACE_START_CPP_WRAPPER_IMPL(name, ...) AUI_DEFINE_INTERFACE_START_FUNCTIONAL_BASE(AUI_METHOD_FUNCTIONAL_IMPL, name, __VA_ARGS__) #define AUI_METHOD(returnValue, name, parameters) returnValue, name, parameters /// Not recommended. This will make your code unnecessarily ugly #define AUI_PARAMS(...) (__VA_ARGS__) /// @deprecated #define AUI_METHODS(...) AUI_BRACKET_SCOPE(__VA_ARGS__) #define AUI_PIN_ODR(name) static const name ## Functional AU_CONCAT(_Zignoreme_aui, __COUNTER__); /// Entrypoint into Aurora Interfaces | Forward declare type #define AUI_INTERFACE_FWD(name, ...) AUI_DEFINE_INTERFACE_START_STRUCT(name, __VA_ARGS__) AUI_DEFINE_INTERFACE_START_CPP_WRAPPER_FWD(name, __VA_ARGS__) /// Entrypoint into Aurora Interfaces | Forward declare and define in a single translation unit #define AUI_INTERFACE_IMPL AUI_INTERFACE_FWD //(name, ...) AUI_DEFINE_INTERFACE_START_STRUCT(name, __VA_ARGS__) AUI_DEFINE_INTERFACE_START_CPP_WRAPPER_IMPL(name, __VA_ARGS__) AUI_PIN_ODR(name) #define AUI_INTERFACE AUI_INTERFACE_FWD