A
A
Artem2018-02-04 12:29:11
C++ / C#
Artem, 2018-02-04 12:29:11

How to organize the class structure?

Hello.

code

Вот у меня есть суперкласс:
class Strategy
{
    public:
        virtual void execute();
        void save(){
            EEPROM.put(source.getEepromPosition(), this);
        }

        Strategy get(bool pos){
            return EEPROM.get(pos ? 0 : 512, Strategy);
        }

    protected:
        ControlButton source;
};

И наследники:
DuplicateStrategy:
#include <Arduino.h>

class DuplicateStrategy : public Strategy
{
    public:
        DuplicateStrategy(Button target, ControlButton controlButton){
            this->target = target;
            this->source = controlButton;
            this->save();
        }

        void execute(){
            this->source.hasCommand() ? this->target.push() : this->target.release();
        }

    private: 
        Button target;

};

MacroStrategy:
#include <Arduino.h>

class MacroStrategy : public Strategy
{
    public:
        MacroStrategy(ControlButton source, MacroPosition positions[]){
            this->source = source;
            this->positions = positions;
            this.save();
        }

        void execute(){
            if(source.hasCommand()){
                for(int i = 0; i < sizeof(this->positions); i++){
                    positions[i].execute();
                }
            }
        }

    private:
        MacroPosition positions[];
}

MultiClickStrategy:
#include <Arduino.h>

class MultiClickStrategy : public Strategy
{
    public:

        MultiClickStrategy(Button target, ControlButton source, unsigned int delay){
            this->target = target;
            this->source = source;
            this->delay_ms = delay;
            this.save();
        }

        void execute(){
            if(source.hasCommand() && this.timeSpent()){
                this->timer = millis();
                target.isPushed() ? target.release() : target.push();
            }
        }
    
    private:
        unsigned long timer;
        unsigned int delay_ms;
        Button target;

        bool timeSpent(){
            return millis() > this->timer + this->delay_ms;
        }
}

The question is this. I want to store the successors of a Strategy in an array of type Strategy[], and for each Strategy I want to be able to call execute().
It seems to me that this is, in principle, real and I did the right thing, but there is one subtlety. I am writing firmware for MK, and I need to store in EEPROM (non-volatile memory) serialized Strategy. There are methods for this:
Get
Put
If I knew which class is in EEPROM, then most likely there would be no problem, but I do not know this, then the question is how to be. I suppose that you can try to specify Strategy as the second parameter of the Get method, but VS says that this is not possible.
In general, I ask for help.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
M
Mercury13, 2018-02-04
@Mercury13

Strategy[N] does not store Strategy descendants, but objects of the Strategy class. Therefore, the array will have to store not the bodies of objects, but pointers.
If your MCU has full memory management with the new operator, it's simple: std::unique_ptr<Strategy> strategies[N]. If not, you have to somehow pervert, and we will not talk about it.
How to serialize? Let's add a small function to the Strategy class
Let the first strategy return, for example, 1=CODE_DUPLICATE, and the second return 2=CODE_MACRO. Serialization, among other things, will write these codes to memory.
After reading the code, we create a Duplicate or Macro, and then we read an object of this class.

std::unique_ptr<Strategy>& thatObject = strategies[i];
switch (getSomeByte) {
case CODE_DUPLICATE:
  thatObject = new DuplicateStrategy();
  break;
case CODE_MACRO:
  thatObject = new MacroStrategy();
  break;
default:
  // можно ничего не делать. Можно сообщить об ошибке.
}
thatObject->read();

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question