Create dynamic amount of Objects

I hope my question is accurate enough to get answered :slight_smile:

class Task {
  private:
    String taskName;
    unsigned long lastTaskCall;
    int callDelay;

   public:
    Task(){}
    
    Task(String taskName, int callDelay = 100, unsigned long lastTaskCall = 0)
    {
        setTaskName(taskName); 
        setCallDelay(callDelay);
        setLastTaskCall(lastTaskCall);        
    }
    
    void setTaskName(String newTaskName)
    {
      taskName = newTaskName;
    }

    void setCallDelay(int newCallDelay)
    {
      callDelay = newCallDelay;
    }

    void setLastTaskCall(unsigned long newLastTaskCall)
    {
      lastTaskCall = newLastTaskCall;
    }

    String getTaskName()
    {
      return taskName;
    }

    int getCallDelay()
    {
      return callDelay;
    }

    unsigned long getLastTaskCall()
    {
      return lastTaskCall;
    }

    /* 
     *  helper function
     *  
     *  
     */

     void showObject()
     {
        String test = "hallo";
        Serial.println((String)"-----Object " + this->getTaskName() + "-----");
        Serial.println((String)"Name: " + this->getTaskName());
        Serial.println((String)"callPeriod: " + this->getCallDelay());
        Serial.println((String)"lastCall: " + this->getLastTaskCall());
        
     }
};


[NOT WORKING PART]

class ManageTasks {
  private:
    Task taskList[maxTasks];
    int taskCounter = 0;
    
  public:
    void addNewTask(String taskName, int callDelay = 100, unsigned long lastTaskCall = 0)
    {
      Task taskName(taskName, callDelay, lastTaskCall); //Use var. taskName as objectName
      taskList[taskCounter] = taskName; //add to taskList to iterate later
    }
    
};


[theoretically Working WAY]
class ManageTasks {
  private:
    Task taskList[maxTasks];
    int taskCounter = 0;
    
  public:
    void addNewTask(String taskName, int callDelay = 100, unsigned long lastTaskCall = 0)
    {
      Task task1(taskName, callDelay, lastTaskCall);
      taskList[taskCounter] = task1;
    }
    
};

Error message:

declaration of 'Task taskName' shadows a parameter

i want to create a dynamic simulating multitasking Class.
my plan is to create the taskList array to add or remove Tasks while program is running e.g add or del a Watchdog or auto Update Task or anything else, but i can't add new Objects to an Array in a dynamic way (using $taskName as objectName).

is there a way to use a variable as object name?

Thanks for help ^^

The arguments to the constructor have been given the same names as private members of the class. The compiler does not know which of the two variables you are referring to.

EDIT: Look at this snippet, two variables with the same name (String & Task named taskName):

void addNewTask(String taskName, int callDelay = 100, unsigned long lastTaskCall = 0)
    {
      Task taskName(taskName, callDelay, lastTaskCall); //Use var. taskName as objectName
      taskList[taskCounter] = taskName; //add to taskList to iterate later
    }

This code is not going to work either sine the instance of "Task" is no longer valid after the method exits.

To do this, you use a linked list. A task holds a pointer to the next task, and a variable at the top of your code holds a pointer to the first task.

To add a task, make a new task object, set it's 'next' equal to the current first task, and set the first task to the objct you have currently created.

To remove a task, point the next pointer of the task in front of it to whatever it's next task is - or, if it is the first task, point the list head at it's next.

You can have a list that you run down, or you can make a circular structure. Each time loop() runs, it increments around to the next task in the circle.

To handle the situation where there are no items in the task list, you can write a buch of code to handle that case, or you can have one special 'do nothing' task that is never removed from the circle.

I think this will work, but I don't have an Uno on hand with which to test it:

-- EDIT -- code edited to fix a bug. If you are reading this, then this is the version you want.

class Task;

class Task {
    static Task *head;
    Task *next;

  protected:
    Task() {
      next = this;
    }

  public:
    static void add(Task *t) {
      t->next = head->next;
      head->next = t;
    }

    static void runNextTask() {
      Task *t = head->next;
      boolean removeMe = head->next->go();

      if (removeMe) {
        head->next = t->next;
        delete t;
      }

      head = head->next;
    }

    /**
      Return true when this task is complete.
    */
    virtual boolean go() = 0;

};


class DoNothing : public Task {
  public:
    boolean go() {
      return false ; // Do nothing never does anything and never completes
    }
} doNothing;

Task *Task::head = &doNothing; // serves as a "keeper" for the circlular loop

class CountToX : public Task {
    const char *name;
    const int X;
    int x = 0;

  public:
    CountToX(const char *name, int X) : X(X), name(name) {}

    boolean go() {
      Serial.print(name);
      Serial.print(' ');
      x++;
      Serial.println(x);
      return x >= X;
    }
};

class CountDown : public Task {
    const char *name;
    int x = 0;

  public:
    CountDown(const char *name, int x) : x(x), name(name) {}

    boolean go() {
      Serial.print(name);
      Serial.print(' ');
      Serial.println(x);
      x --;
      return x <= 0;
    }
};



void setup() {
  Serial.begin(9600);
  Task::add(new CountDown("TEN!", 10));
  Task::add(new CountToX("Five", 5));
}

void loop() {
  Task::runNextTask();
}

You don't need a variable-name because they are all in a list:

    void addNewTask(String taskName, int callDelay = 100, unsigned long lastTaskCall = 0)
    {
      taskList[taskCounter] = Task(taskName, callDelay, lastTaskCall);
    }

You should add 1 to "taskCounter" after to put the new task in the list.