blynkkk / blynk-library

Blynk library for IoT boards. Works with Arduino, ESP32, ESP8266, Raspberry Pi, Particle, ARM Mbed, etc.
https://blynk.io
MIT License
3.83k stars 1.38k forks source link

A way to disable automatic Blynk instance creation #439

Closed mr-deimos closed 2 years ago

mr-deimos commented 5 years ago

Blynk library version: [0.5.4] IDE: [Platform.IO/] IDE version: [...] Board type: [ESP8266] Additional modules: [...]

Scenario, steps to reproduce

I'm creating a few devices with the same basic configuration and some shared functionality. So i'm trying to wrap Blynk in a class, then use derived classes for my devices. If is included in the base class header and i compile the project with only the base class, everything works as expected. However when i add the derived class, i get en error about Blynk already being defined - even if i don't explicitly include BlynkSimpleESP366.h in the derived class header. I guess it gets included along with the parent header. Also, i can't use BlynkWifi* pointer returned by my base class elsewhere (like in main.cpp), because the BlynkWifi class is not declared there. Of course if i include the blynk header in main.cpp i'll get another "already defined" error because the Blynk instance is created in that header.

Expected Result

I'd like to have a way to disable automatic creation of blynk instance. For example ArduinoOTA does this by preprocessor directives:

#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_ARDUINOOTA)
extern ArduinoOTAClass ArduinoOTA;
#endif

Adding such condition to BlynkSimple*.h would be simple enough, for example this should do the trick:

#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_BLYNK)
  static WiFiClient _blynkWifiClient;
  static BlynkArduinoClient _blynkTransport(_blynkWifiClient);
  BlynkWifi Blynk(_blynkTransport);
#endif

By default it would work exactly as original code, but it would enable more elastic use of Blynk for advanced users. And the header should be safe to include in multiple files.

vshymanskyy commented 5 years ago

Cool. Thanks I think we will implement it soon.

krzmaz commented 4 years ago

@vshymanskyy Any updates on that topic? I've come across the same problem, and think that solution proposed by mr-deimos would be optimal. If we introduce a brand new environment variable like NO_GLOBAL_BLYNK, the chance of breaking legacy code is astronomically small. Every user could use what they need.

jpasqua commented 2 years ago

I've made this change mechanically in my fork. I will submit a pull request. The boilerplate looks like:

#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_BLYNK)
  static WiFiClient _blynkWifiClient;
  static BlynkArduinoClient _blynkTransport(_blynkWifiClient);
  BlynkWifi Blynk(_blynkTransport);
#else
  extern BlynkWifi Blynk;
#endif

Existing code should work as it does today. New code can define NO_GLOBAL_INSTANCES and NO_GLOBAL_BLYNK to avoid multiple definitions. In my client code I have a wrapper include file that looks something like this:

#define NO_GLOBAL_INSTANCES
#define NO_GLOBAL_BLYNK

#include <BlynkSimpleEsp8266.h>

#undef NO_GLOBAL_INSTANCES
#undef NO_GLOBAL_BLYNK

I use this everywhere for code that is talking to Blynk. I #includeBlynkSimpleEsp8266.hin one place without the #defines to get a single instance ofBlynk`.