Giter VIP home page Giter VIP logo

panku's Introduction

PANKU

Panku is a header-only library designed to help with static initialisation of multiple objects, in cases where there are complex order dependencies between them.

It was created for an embedded use case. As an embedded project grows, there is a pattern that keeps repeating itself: a monolithic file, usually named some variant of "InitialiseDevices", which contains all the code necessary to construct and interconnect elements of the system of varying abstraction levels, such as the scheduler, terminal, UART and Flash drivers, etc.

This file can easily grow out of control and become a maintenance burden. Furthermore, anyone wanting to add a new object to the static initialisation list needs to figure out exactly where to put it, which is time consuming.

Panku aims to solve that issue by allowing the user to explicitly state these object dependencies, solving the dependency graph at compile time. Panku is not a dependency injection framework, it does its job without invading the codebase.

How to use

To integrate Panku in your project, include the file "named_panku.h" and use the following macro:

  • NAMED_PANKU_LIST: Declares a panku name and the list of classes that panku will be in charge of initialising. Each class is introduced as a dependency list, followed by the classes it depends on. Example:

    #include "named_panku.h"
    #include "UART.h"
    #include "Flash.h"
    #include "FileSystem.h"
    #include "Terminal.h
    
    NAMED_PANKU_LIST
    (
       devices,
       NAMED_INSTANCE(FileSystem, Flash),     // File system depends on a flash driver
       NAMED_INSTANCE(Flash),                 // Flash driver has no dependencies
       NAMED_INSTANCE(Terminal, UART, Flash), // Terminal depends on both drivers
       NAMED_INSTANCE(UART)                   // UART is also dependency free
    );

    Note that this list can be defined in any order, the dependency graph will be solved at compile time. In case of a circular dependency, a static_assert will stop the program from compiling and prevent runtime undefined behaviour.

    What this macro does is define a class named "Panku", that you can declare and instantiate once in one of your translation units. Panku provides two methods, "Initialise" and "Get". Initialise performs the construction of all static objects, while Get retrieves a reference for you to use. It's possible to skip "Initialise", in which case it will be called lazily in the first use of "Get".

    panku_devices devices;
    devices.Get<Flash>(); // Returns a reference to the Flash instance
  • Important: As a panku grows, it takes more resources to solve the "dependency puzzle". It is recommended that you split large pankus up to avoid excessive RAM and CPU use at compile-time.

Finally, even though Panku can figure out in which order to initialise your devices, it has no way to know what constructor arguments you want. To specify how Panku should build each of the listed devices, you must define a function with the following format for each of them (they can be defined anywhere):

template<>
MyClass& ConstructAndInitialise<MyClass&>() {
   static MyClass myObject;
   return myObject;
}

Multiple object instances:

If you require multiple instances of the same class, you can use NAMED_COLLECTION(N, Class, Deps...) in place of NAMED_INSTANCE(Class, Deps...). You will have to supply N constructor functions of the form:

Class& ConstructAndInitialise<Class&, 0>;
Class& ConstructAndInitialise<Class&, 1>;
...
Class& ConstructAndInitialise<Class&, N>;

These constructor functions will be called sequentially. To retrieve objects of this type from the Panku class, you will have to call the templated form of Get:

devices.Get<Class&, 1>(); // Retrieves the second object of type "Class"

Iterating over objects by their common parent:

Panku includes a very handy way of iterating over all elements who have a common parent:

devices.ForEach<ParentType>([](auto& object) {
   object.DoSomething();
});

Iterations over objects with arbitrary type traits will be supported in the future (i.e. "Do something to all classes with a trivial constructor");

panku's People

Contributors

pablomansanet avatar mdodkins avatar laurent-rabatel-bluefruit avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.