Created
January 26, 2022 06:19
-
-
Save LiterallyVoid/dc55dfd305e53560ef2134670577f8f2 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| #define CONCAT2(x, y) x ## y | |
| #define CONCAT(x, y) CONCAT2(x, y) | |
| #define COMPONENT(...) | |
| #define DEFEVENT(...) | |
| #define DEFBUBBLE(...) | |
| struct context { | |
| #define DEFCONTEXT(type, name, default) type name; | |
| #include "components.i" | |
| #undef DEFCONTEXT | |
| }; | |
| struct context context_default(void) { | |
| struct context ctx; | |
| #define DEFCONTEXT(type, name, default) ctx.name = default; | |
| #include "components.i" | |
| #undef DEFCONTEXT | |
| return ctx; | |
| } | |
| #define DEFCONTEXT(...) | |
| // EVENTS & BUBBLES | |
| #undef DEFEVENT | |
| #undef DEFBUBBLE | |
| #define DEFEVENT(name, ...) struct event_##name { __VA_ARGS__ }; const int event_##name = __LINE__; | |
| #define DEFBUBBLE(name, ...) struct bubble_##name { __VA_ARGS__ }; | |
| #include "components.i" | |
| #undef DEFEVENT | |
| #undef DEFBUBBLE | |
| #define DEFEVENT(...) | |
| #define DEFBUBBLE(...) | |
| #undef DEFBUBBLE | |
| #define DEFBUBBLE(name, ...) struct { void *data; void (*fn)(void *data, struct bubble_##name *event); } name; | |
| struct bubble_handlers { | |
| #include "components.i" | |
| }; | |
| #undef DEFBUBBLE | |
| #define DEFBUBBLE(...) | |
| #undef COMPONENT | |
| #define PROP(...) | |
| #define STATE(...) | |
| #define ON(...) | |
| #define CATCH(...) | |
| #define LET(...) | |
| #define PROVIDE(...) | |
| #define USE(...) | |
| #define INSTANCE(...) | |
| // DEFINE PROPS | |
| #define COMPONENT(name, ...) struct name##_props { __VA_ARGS__ }; | |
| #undef PROP | |
| #define PROP(type, name) type name; | |
| #include "components.i" | |
| #undef PROP | |
| #define PROP(...) | |
| #undef COMPONENT | |
| // DEFINE STATES | |
| #define COMPONENT(name, ...) struct name##_state { struct name##_props ens_props; struct context ctx; __VA_ARGS__ }; | |
| #undef STATE | |
| #define STATE(type, name, ...) type name; | |
| #undef INSTANCE | |
| #define INSTANCE(component, ...) int CONCAT(ens_state_count_, __LINE__); int CONCAT(ens_state_count_pre_, __LINE__); struct component##_state CONCAT(ens_state_, __LINE__)[8]; | |
| #undef USE | |
| #define USE(component, ...) int CONCAT(ens_state_count_, __LINE__); int CONCAT(ens_state_count_pre_, __LINE__); struct component##_state CONCAT(ens_state_, __LINE__)[8]; | |
| #include "components.i" | |
| #undef STATE | |
| #define STATE(...) | |
| #undef USE | |
| #define USE(...) | |
| #undef INSTANCE | |
| #define INSTANCE(...) | |
| #undef COMPONENT | |
| // DEFINE DEINITS | |
| #define COMPONENT(name, ...) void name##_deinit(struct name##_state *state) { __VA_ARGS__ }; | |
| #undef INSTANCE | |
| #define INSTANCE(component, ...) for (int i = 0; i < state->CONCAT(ens_state_count_, __LINE__); i++) component##_deinit(&state->CONCAT(ens_state_, __LINE__)[i]); | |
| #undef USE | |
| #define USE(component, ...) for (int i = 0; i < state->CONCAT(ens_state_count_, __LINE__); i++) component##_deinit(&state->CONCAT(ens_state_, __LINE__)[i]); | |
| #include "components.i" | |
| #undef USE | |
| #define USE(...) | |
| #undef INSTANCE | |
| #define INSTANCE(...) | |
| #undef COMPONENT | |
| // DEFINE DEFAULT | |
| #define COMPONENT(name, ...) void name##_default(struct name##_state *state) { __VA_ARGS__ }; | |
| #undef STATE | |
| #define STATE(type, name, ...) state->name = __VA_ARGS__; | |
| #undef INSTANCE | |
| #define INSTANCE(component, ...) state->CONCAT(ens_state_count_, __LINE__) = 0; | |
| #undef USE | |
| #define USE(component, ...) state->CONCAT(ens_state_count_, __LINE__) = 0; | |
| #include "components.i" | |
| #undef STATE | |
| #define STATE(...) | |
| #undef USE | |
| #define USE(...) | |
| #undef INSTANCE | |
| #define INSTANCE(...) | |
| #undef COMPONENT | |
| // DECLARE | |
| #define COMPONENT(name, ...) \ | |
| struct context name##_build(struct name##_state *state, struct context ctx, struct name##_props props); \ | |
| struct context name##_init(struct name##_state *state, struct context ctx, struct name##_props props); | |
| #include "components.i" | |
| #undef COMPONENT | |
| // DEFINE PREBUILDS | |
| #define COMPONENT(name, ...) void name##_prebuild(struct name##_state *state) { __VA_ARGS__ }; | |
| #undef INSTANCE | |
| #define INSTANCE(component, ...) state->CONCAT(ens_state_count_pre_, __LINE__) = state->CONCAT(ens_state_count_, __LINE__); state->CONCAT(ens_state_count_, __LINE__) = 0; | |
| #undef USE | |
| #define USE(component, ...) state->CONCAT(ens_state_count_pre_, __LINE__) = state->CONCAT(ens_state_count_, __LINE__); state->CONCAT(ens_state_count_, __LINE__) = 0; | |
| #include "components.i" | |
| #undef USE | |
| #define USE(...) | |
| #undef INSTANCE | |
| #define INSTANCE(...) | |
| #undef COMPONENT | |
| // DEFINE POSTBUILDS | |
| #define COMPONENT(name, ...) void name##_postbuild(struct name##_state *state) { __VA_ARGS__ }; | |
| #undef INSTANCE | |
| #define INSTANCE(component, ...) for (int i = state->CONCAT(ens_state_count_, __LINE__); i < state->CONCAT(ens_state_count_pre_, __LINE__); i++) { component##_deinit(&state->CONCAT(ens_state_, __LINE__)[i]); } | |
| #undef USE | |
| #define USE(component, ...) for (int i = state->CONCAT(ens_state_count_, __LINE__); i < state->CONCAT(ens_state_count_pre_, __LINE__); i++) { component##_deinit(&state->CONCAT(ens_state_, __LINE__)[i]); } | |
| #include "components.i" | |
| #undef USE | |
| #define USE(...) | |
| #undef INSTANCE | |
| #define INSTANCE(...) | |
| #undef COMPONENT | |
| // DEFINE BUILDS | |
| #define COMPONENT(name, ...) struct context name##_build(struct name##_state *state, struct context ctx, struct name##_props props) { name##_prebuild(state); __VA_ARGS__ name##_postbuild(state); state->ctx = ctx; return ctx; }; | |
| #undef STATE | |
| #define STATE(type, name, ...) type name = state->name; | |
| #undef PROP | |
| #define PROP(type, name) type name = props.name; | |
| #undef PROVIDE | |
| #define PROVIDE(name, ...) ctx.name = __VA_ARGS__; | |
| #undef LET | |
| #define LET(type_value, ...) type_value = __VA_ARGS__; | |
| #define CTX(name) ctx.name | |
| #undef INSTANCE | |
| #define INSTANCE(component, ...) if (state->CONCAT(ens_state_count_, __LINE__) < state->CONCAT(ens_state_count_, __LINE__)) { \ | |
| component##_build(&state->CONCAT(ens_state_, __LINE__)[state->CONCAT(ens_state_count_, __LINE__)++], ctx, (struct component##_props) { __VA_ARGS__ }); \ | |
| } else { \ | |
| component##_init(&state->CONCAT(ens_state_, __LINE__)[state->CONCAT(ens_state_count_, __LINE__)++], ctx, (struct component##_props) { __VA_ARGS__ }); \ | |
| } \ | |
| #undef USE | |
| #define USE(component, ...) if (state->CONCAT(ens_state_count_, __LINE__) < state->CONCAT(ens_state_count_, __LINE__)) { \ | |
| ctx = component##_build(&state->CONCAT(ens_state_, __LINE__)[state->CONCAT(ens_state_count_, __LINE__)++], ctx, (struct component##_props) { __VA_ARGS__ }); \ | |
| } else { \ | |
| ctx = component##_init(&state->CONCAT(ens_state_, __LINE__)[state->CONCAT(ens_state_count_, __LINE__)++], ctx, (struct component##_props) { __VA_ARGS__ }); \ | |
| } \ | |
| #include "components.i" | |
| #undef STATE | |
| #define STATE(...) | |
| #undef PROP | |
| #define PROP(...) | |
| #undef PROVIDE | |
| #define PROVIDE(...) | |
| #undef LET | |
| #define LET(...) | |
| #undef CTX | |
| #define CTX(...) | |
| #undef USE | |
| #define USE(...) | |
| #undef INSTANCE | |
| #define INSTANCE(...) | |
| #undef COMPONENT | |
| // DEFINE INITS | |
| #define COMPONENT(name, ...) struct context name##_init(struct name##_state *state, struct context ctx, struct name##_props props) { name##_default(state); name##_build(state, ctx, props); }; | |
| #include "components.i" | |
| #undef COMPONENT | |
| // EVENT HANDLERS | |
| #define BUBBLE(x, ...) bubble_handlers.x.fn(bubble_handlers.x.data, &(struct bubble_##x) { __VA_ARGS__ }); | |
| #define COMPONENT(name, ...) __VA_ARGS__ | |
| #undef CATCH | |
| #define CATCH(event, e, ...) void CONCAT(ens_bubble_handler_, __LINE__)(void *data, struct bubble_##event *e) { __VA_ARGS__ } | |
| #include "components.i" | |
| #undef CATCH | |
| #define CATCH(...) | |
| #undef COMPONENT | |
| #undef CTX | |
| #define CTX(name) state->ctx.name | |
| #define COMPONENT(name, ...) void name##_event_i(struct name##_state *state, int event, void *event_data, struct bubble_handlers bubble_handlers) { __VA_ARGS__ } void name##_event(struct name##_state *state, int event, void *event_data) { name##_event_i(state, event, event_data, (struct bubble_handlers) { 0 }); name##_build(state, context_default(), state->ens_props); } | |
| #undef STATE | |
| #define STATE(type, name, ...) type *name = &state->name; | |
| #undef ON | |
| #define ON(ev, e, ...) if (event == event_##ev) { struct event_##ev *e = event_data; __VA_ARGS__ } | |
| #undef CATCH | |
| #define CATCH(ev, e, ...) bubble_handlers.ev.data = state; bubble_handlers.ev.fn = CONCAT(ens_bubble_handler_, __LINE__); | |
| #undef USE | |
| #define USE(component, ...) for (int i = 0; i < state->CONCAT(ens_state_count_, __LINE__); i++) { component##_event_i(&state->CONCAT(ens_state_, __LINE__)[i], event, event_data, bubble_handlers); } | |
| #undef INSTANCE | |
| #define INSTANCE(component, ...) for (int i = 0; i < state->CONCAT(ens_state_count_, __LINE__); i++) { component##_event_i(&state->CONCAT(ens_state_, __LINE__)[i], event, event_data, bubble_handlers); } | |
| #include "components.i" | |
| #undef ON | |
| #define ON(...) | |
| #undef COMPONENT | |
| #undef DEFCONTEXT | |
| #undef DEFEVENT | |
| #undef DEFBUBBLE | |
| #undef PROP | |
| #undef STATE | |
| #undef ON | |
| #undef CATCH | |
| #undef LET | |
| #undef PROVIDE | |
| #undef USE | |
| #undef INSTANCE |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment