Chris GW Green
Chris GW Green

Reputation: 1213

Call parent function from child instance - C++

Apologies if my c++ terminology if off. I come from a web/js/react background and could well be thinking about this the wrong way. I've tried quite a lot of solutions but now I'm a little in need.

Intro:

I'm exploring esp32 devices with touch screens and trying to make a keyboard to enter a wifi password.

Following a web approach, I hope to keep specific functionality in specific components. As such I have a keyboard which handles all the key press logic to type the password, which I want to then pass back to the wifiView which then handles the wifi connectivity behaviour etc.

Scenario:

The wifiView instantiates fine, which in course instantiates the keyboard correctly, but I can't find a way to pass the submission back to the wifiView. In web, that would be a callback whereby you pass a function (in this case I understand is a pointer to a function) to call on the parent from the child with the password.

What I've tried

I've tried passing through a click function:

void initKeyboard(TFT_eSPI *tft, void (*onClick)(char *letter)); // <--

But as the function is on the wifiView instance I get static function errors.

I've tried passing the wifiView instance to the keyboard instance to call the function directly:

void initKeyboard(TFT_eSPI *tft, WifiView *_wifiView);           //<--

This leads to type errors and circular dependencies, which then lead me to forward declarations etc., and none of them worked.

I've tried lambda functions, but the moment I pass this or & as a dependency it just fails to build.

My gut it telling me I'm missing something obvious and would very much appreciate some help being pointed in the right direction.

Code so far

Keyboard.h

#ifndef __Keyboard_H__
#define __Keyboard_H__

#include <Arduino.h>
#include <TFT_eSPI.h>
// #include <WifiView.h> // <-- Circular dep

#define BG 0x0085
#define COLOR 0xffff

enum KeyboardState { LOWERCASE = 1, CAPS = 2, NUM1 = 3, NUM2 = 4 };

class WifiView; // <-- Forward dec

class Keyboard {
public:
  Keyboard(void);
  void initKeyboard(TFT_eSPI *tft, void (*onClick)(char *letter)); // <--
  void initKeyboard(TFT_eSPI *tft, WifiView *_wifiView);           //<--

  void contains(int16_t x, int16_t y);
  void renderKeyboard();
  void press();
  void renderKey(TFT_eSprite *, const char *, uint16_t, uint16_t);

private:
  TFT_eSPI *_tft;
  WifiView *_wifiView; // <---

Keyboard.cpp - what I'm hoping to trigger

  if (isSubmitDown) {
    isSubmitDown = false;

    _onClick(_word);
  }

wifiView.h

class WifiView {
public:
  WifiView(void);

  void init(TFT_eSPI *tft,
            void (*onClick)(queej_enums::ViewState newScreenState));
  void contains(int16_t x, int16_t y);
  void renderWifiView();
  void press();
  void homeButton();

private:
  TFT_eSPI *_tft;
  Keyboard keyboard = Keyboard();

  void keyboardSubmit(char *password);

WifiView.cpp

void WifiView::init(TFT_eSPI *tft,
                    void (*onClick)(queej_enums::ViewState newScreenState)) {
  _tft = tft;
  _onClick = onClick;

  // keyboard->initKeyboard(&tft, this)

  // keyboard.initKeyboard(tft, WifiView::keyboardClick);

  // keyboard.initKeyboard(tft, &WifiView::keyboardClick);

  // keyboard.initKeyboard(tft, [&](char *word) {
  //   Serial.println(word);
  // });
}

Upvotes: -1

Views: 68

Answers (0)

Related Questions