Wywoływanie metody innego obiektu

0

Hej.
Piszę kod do sterownika LEDów RGB WiFi w C++. Całość jest oparta na ESP8266 jednak problem mam raczej natury programowej. Mianowicie potrzebuję zrobić klasę TimerClass, która, między innymi, będzie przechowywać obiekt jakiejś innej klasy (najlepiej dowolnej) oraz dowolną metodę tegoż obiektu. Dodatkowo potrzebuję napisać dwie metody dla obiektów klasy TimerClass, jedną, która będzie przyjmowała obiekt wraz z metodą do przypisania, oraz drugą, która będzie później tą metodę wykonywała. Wiem, że brzmi trochę zagmatwanie :/ Sama klasa po prostu sprawdza czy upłynął zadany czas i jeżeli tak to ma uruchomić wcześniej przypisaną wersję metodę konkretnego obiektu. Ale właśnie z tym przypisaniem metody jest ogromy problem.
Tutaj mam kod tej klasy (tyle ile udało mi się napisać):

class TimerClass
{
 protected:
	 unsigned long _time;
	 unsigned int _wait;
	 bool output;
	 //Tu powinny być zmienne do zapisania obiektu i metody
 public:

	 TimerClass() {}
	 TimerClass(unsigned long time);
	 bool Try();
	 void Set(/*Obiekt i jego metoda*/);
}


TimerClass::TimerClass(unsigned long time)
{
	_time = millis();
	_wait = time;
	output = false;
}

bool TimerClass::Try()
{
	if (output) return true;
	unsigned long tmp0 = millis();
	if (abs(tmp0 - _time) >= _wait) {
		//W tym miejscu powinien być kod wywołujący metodę na obiekcie
		output = true;
		return true;
	}
	return false;
}

void TimerClass::Set(/*Obiekt i jego metoda*/)
{
	//Tu ma być kod zapisujący obiekt i metodę
}

Tutaj jest miejsce wywołania:


class KlasaA
{
public:
	void Metoda1();
	void Metoda2();

};

class KlasaB
{
public:
	void MetodaX();
	void MetodaY();

};

KlasaA obiekt1;
KlasaB obiekt2;

TimerClass timer1  = new TimerClass(10000);
TimerClass timer2 = new TimerClass(20000);
timer1.Set(/*Przypisanie Metoda1 obiektu obiekt1 */)
timer2.Set(/*Przypisanie MetodaY obiektu obiekt2 */)

while(true){

	//Jakiś kod
	timer1.Try();
	timer2.Try();


}

Całość ma działać jako pseudo wielowątkowe wykonywanie programu na ESP8266. Głowię się nad tym już kilka tygodni i nic mi nie przychodzi do głowy, cały czas jak uda mi się rozwiązać jeden błąd to znajduję inny. Samo zapisanie obiektu, a raczej wskaźnika na niego nie jest problemem, gorzej jest z tą metodą, nie mam kompletnie pomysłu jak to napisać aby było w miarę uniwersalne. Na przykład żeby działało dla wszystkich obiektów klas dziedziczących z jakiejś klasy wirtualnej. Jeżeli nie da się tak jak próbuję to najwyżej po prostu zrezygnuję

1

Ja bym zamiast kombinować z dowolnym obiektem, użył jakiegoś interfejsu, np.

struct Callback {
  virtual void execute() = 0;
  virtual ~Callback() {}
};

class TimerCallback : public Callback {
  void execute() override {
    // robisz co tam masz robić  
  }
};

//a w samym TimerClass
Callback& _timeoutCallback ; //przypisanie w konstruktorze, jeżeli w set to musi to być wskaźnik

//a wywołanie proste, dla wskaźnika oczywiście -> zamiast kropki
_timeoutCallback.execute();

EDIT: wirtualny destruktor oczywiście powinien być.

1
//Tu powinny być zmienne do zapisania obiektu i metody
std::function<void()> stored_method;
void Set(std::function<void()> method) {
stored_method = method;
}
 //W tym miejscu powinien być kod wywołujący metodę na obiekcie
stored_method();
	timer1->Set([&obiekt1]() {
		obiekt1.Metoda1();
	});
	timer2->Set([&obiekt2]() {
		obiekt2.MetodaY();
	});

i będzie śmigać
inna sprawa że
a) źle liczysz czas, nie powinno być tam abs, który btw jest niezdefiniowany dla unsigned, użyj

	if (millis() >= _time + _wait) {

b) jeśli chcesz w swoim finalnym kodzie tak używać tego timera, to jest to bardzo naiwne rozwiązanie (w sensie czekanie w while i sprawdzanie)

0

Btw, ten Twój kod jest odpalany bezpośrednio na ESP?

Bo jeśli tak, to brakuje tam yieldów (https://stackoverflow.com/questions/34497758/what-is-the-secret-of-the-arduino-yieldfunction), więc możesz mieć problemy z utrzymaniem stabilności WiFi w momencie, gdy sterowanie wejdzie do pętli.

0

Samo zachowywanie metody myślę, że rozwiązał kolega @amd ale jeśli dodatkowo chcesz mieć

kod zapisujący obiekt i metodę

To do zapisania obiektu potrzebujesz współdzielonych wskaźników, które przyjmować będziesz jako argument tej metody. Chociaż to co opisałeś brzmi bardziej jak zwykły callback, który możesz przekazać właśnie lambdą.

1 użytkowników online, w tym zalogowanych: 0, gości: 1