samedi 24 décembre 2022

Instantiating an array of function pointers after discovering how many elements it needs to have

My general Idea is to form an event driven code flow in my Arduino projects. I had nice experience with events in C# but since Arduino uses C++ and doesn't have required base (so far as I know) I can't use this technique natively. The general idea is to create a class Event which supports the following API:

class Event {
    void Add(function f);
    void Remove(function f);
};

The event class will be than managed with the help of another object which will call or 'unwrap' all the events in a loop function - the part of the program that executes on the Arduino board in a loop.

now the problem with this idea is that it requires memory allocation (vector) to add and store these functions, it may be acceptable for machines with large amount of RAM, but for small ones it can be not efficient enough, for Arduino it can take more time also so the time managed processes can be affected.

I am not sure if it is possible or there is another solution, but my idea is to use some 'template-magic' and tune all the functions to the events in the setup function, which runs once as an initialization before the loop executes. By this I want to avoid allocations and make these events immutable (only after all the functions are tuned) but this seems not possible because to declare an array we need to set its size but in this case the size would be discovered only in the end.

The code I would like to clean, if possible, looks like this:

int button_pin1 = 1;
int button_pin2 = 2;
int button_pin3 = 3;
int button_pin4 = 4;
int button_pin5 = 5;
int button_pin6 = 6;
int button_pin7 = 7;
int button_pin8 = 8;
int button_pin9 = 9;
int button_pin10 = 10;




void blinkled(int button_pin){
  if (button_pin % 2 == 0)
    digitalWrite(LED_BUILTIN, HIGH);
}

void printToDisplay(int button_pin);
void doImportantStuff(int button_pin);
void implementSuperNatural(int button_pin);

void setup() {
 for(int i = button_pin1; i= < button_pin10; i++)
    pinMode(i, INPUT);
}

 
void loop() {
 if (digitalRead(button_pin1){
    blinkLed(button_pin1);
 })
if (digitalRead(button_pin2){
   blinkLed(button_pin2);
  printToDisplay(button_pin2);
})
if (digitalRead(button_pin3){
printToDisplay(button_pin3);
doImportantStuff(button_pin3);
implementSuperNatural(button_pin3);
})

// write if statements for any button that was pressed with any combination of functions above ...
}

after the cleanup I would like it to look like this: `



void blinkled(int button_pin){
  if (button_pin % 2 == 0)
    digitalWrite(LED_BUILTIN, HIGH);
}

void printToDisplay(int button_pin);
void doImportantStuff(int button_pin);
void implementSuperNatural(int button_pin);

//Button will be a class that reperesents a real button.
Button buttons[] = Button::from_pins(1,2,3,4,5,6,7,8,9,10);


void setup() {
  for(int i = 0; i < sizeof(buttons) / sizeof(buttons[0]; i++))
    buttons[i].activate();
  buttons[0].onClick += printToDisplay;
  buttons[3].onClick += {doImportantStuff, printToDisplay};     // the += operator resembles the 'add' method in the API 
  buttons[10].onClick += {blinkLed, implementSuperNatural}; 

  if constexpr (//some condition){
    buttons[3].onClick += printToDisplay;
    buttons[10].onClick -= blinkled; // the -= opreator resembles the remove method in the API
  }
  

 
void loop() {
  EventSchduler::run();
}

`

This 'clean' code written above is not formatted well but I hope it makes the idea clearer.

Maybe the whole Idea is completely wrong, and many will say it's a waste or the question is unclear, or the technique is simply bad. I just want to get people's opinions and learn.

Aucun commentaire:

Enregistrer un commentaire