arkhipenko / TaskScheduler

Cooperative multitasking for Arduino, ESPx, STM32, nRF and other microcontrollers
http://playground.arduino.cc/Code/TaskScheduler
BSD 3-Clause "New" or "Revised" License
1.26k stars 230 forks source link

inline specifier dissapeared in 2.5.0, causing compile error #42

Closed bedomarci closed 6 years ago

bedomarci commented 6 years ago

Hi! Why did you remove inline specifiers of methods in v2.5.0? They came in v2.2.0 simply dissapear after v2.3.0. I am using Task class in my template class which is producing linking errors. Each derived class giving me multiple definition error for each method of your library. However I'd like to use features from v2.5.0, so i cant go back to v2.3.0. Is there any chance to restore them?

Marci

arkhipenko commented 6 years ago

The idea behind inlines was to make TS compatible with multiple tab scetches, which we achieved by other means (splitting .H files into definitions and implementation). I don't have your use case in my scenarios, so never tested before release. Could you please create an example sketch (similar to existing examples), and I will see how it should be resolved?.

Cheers.

bedomarci commented 6 years ago

I prepared an example. Program contains a generic class as parent (TemplateClass) and 2 specialized, derived classes (DerivedClassA, DerivedClassB). Generic class is header file only, has no implementation file. Also all template methods are inline by default! Each member class (Task in this case) must have the same structure. As long as ur lib contained inline specifier sketch compiled. (@2.3.0) (explanation here)

TemplateClass

#ifndef CLASSTEMPLATE
#define CLASSTEMPLATE

#include <TaskScheduler.h>  //comment out this line to avoid linking error

template<typename T>
class TemplateClass {
public:
  void someMethod(T input);
  virtual void anotherDerivedMethod(T input)=0;
protected:
  Task _taskToDo; //comment out this line to avoid linking error
};

template<typename T>
void TemplateClass<T>::someMethod(T input) {
    //template class method implementation
}
#endif

DerivedClassA declaration - DerivedClassA.hpp

#ifndef CLASSA
#define CLASSA

#include "TemplateClass.hpp"

class DerivedClassA : public TemplateClass<char> {
public:
  void anotherDerivedMethod(char input);
};
#endif

implementation - DerivedClassA.cpp

#include "DerivedClassA.hpp"
void DerivedClassA::anotherDerivedMethod(char input) {
  //derived class method implementation
}

DerivedClassB - almost identical to DerivedClassA, but different specialization declaration - DerivedClassB.hpp

#ifndef CLASSB
#define CLASSB

#include "TemplateClass.hpp"

class DerivedClassB : public TemplateClass<int> {
public:
  void anotherDerivedMethod(int input);
};
#endif

implementation - DerivedClassB.cpp

#include "DerivedClassB.hpp"

void DerivedClassB::anotherDerivedMethod(int input) {
  //derived class method implementation
}

main.cpp

#include <Arduino.h>
#include "DerivedClassA.hpp"
#include "DerivedClassB.hpp"

DerivedClassA* ca;
DerivedClassB* cb;

void setup() {
  ca = new DerivedClassA();
  cb = new DerivedClassB();
}
void loop() {}

environment:

Best, Marci

arkhipenko commented 6 years ago

Thanks. Will look into this after the holidays.

arkhipenko commented 6 years ago

Hi, Did you check the multi-tab example? I think the issue is that you need to include TaskScheduler.h into main.cpp, and TaskSchedulerDeclarations.h into all the HPP files. Does that work?

mutiltab example

bedomarci commented 6 years ago

Hi, I did. Unfortunately it does not work with template classes. As soon as I instantiate a 2nd specialization of the generic class it throws linker error. Generic class must contain declaration only. I modified TaskScheduler.h to make it work. All method got an inline specifier (as u did int 2.3.0) and it works just fine.

arkhipenko commented 6 years ago

Hi,

Please test 2.5.2 from the "testing" branch and use #define _TASK_INLINE compile directive Does this fix the issue?

bedomarci commented 6 years ago

Compiles with no error! Thank you!

arkhipenko commented 6 years ago

OK. I will test a little more and update master branch later.