LibJuno 0.32.0
LibJuno is a lightweight C99 library designed specifically for embedded systems.
Loading...
Searching...
No Matches
Module Docs

Overview

LibJuno implements dependency injection through modules and API traits. This is very similar to the Rust paradigm. There are 3 components to modules within LibJuno:

  • The module
  • The module root
  • The module derivations

The Module Root

Before talking about the module itself we need to go over the module root.

  • The module root is a common set of member variables shared across all module derivations and implementations.
  • When a module is derived there is a compile-time gurantee that the module can be safely up-cast to the module root.
    • All derivations of the module can up-cast to the module root.
  • The module root always provides the following as defined by the macros:
    • ptApi – A pointer to the API traits
    • _pfcnFailureHandler – A failure handler callback
    • _pvFailurUserData – User defined data pointer to provide to the failure handler callback
  • Members within the module root should be freestanding
    • The real power within DI is to isolate dependencies
    • The module root should not contain any dependencies. Ideally the module root should only contain types supported by your freestanding C standard, like C99 or C11. This enables highly portable modules.
    • Implementation details and dependencies belong in the module derivations

Implementing a Module: Derivations

  • Concrete implementations for a module are created through deriving the module.
  • A derivation is guranteed to have the module root as the the first member. Module derivations can always be safely up-cast to the module root.
  • The module derivations can contain implementation specific details, dependencies, and other private memebers.
  • You can think of the members placed within the derivation as "private" in C++ terms

The Module

Now with a background on the module root and module derivations, we can talk about the module.

  • The module is a union of all possible derivations, including the root.
  • The module is forward-declared. Module implementations will provide a default implementation of the module that can be overridden when ..._CUSTOM is defined.
    • The user of the module would define ..._CUSTOM if they want polymorphic behavior.
  • API traits are provided a pointer to the module.

How to Define The Module Union

Below is an example of defining a module union:

union MY_MODULE_T JUNO_MODULE(MY_MODULE_API_T, MY_MODULE_ROOT_T,
MY_MODULE_DERIVATION_1_T;
MY_MODULE_DERIVATION_2_T;
MY_MODULE_DERIVATION_3_T;
);
#define JUNO_MODULE(API_T, ROOT_T, derived)
Definition module.h:154