mirror of
https://github.com/wled/WLED.git
synced 2025-04-24 06:47:18 +00:00
Convert BusManager class to namespace
- use unique_ptr/make_unique for busses
This commit is contained in:
parent
32a75c1ff5
commit
ee7ec20f29
@ -63,6 +63,8 @@ uint8_t realtimeBroadcast(uint8_t type, IPAddress client, uint16_t length, const
|
||||
#define W(c) (byte((c) >> 24))
|
||||
|
||||
|
||||
static ColorOrderMap _colorOrderMap = {};
|
||||
|
||||
bool ColorOrderMap::add(uint16_t start, uint16_t len, uint8_t colorOrder) {
|
||||
if (count() >= WLED_MAX_COLOR_ORDER_MAPPINGS || len == 0 || (colorOrder & 0x0F) > COL_ORDER_MAX) return false; // upper nibble contains W swap information
|
||||
_mappings.push_back({start,len,colorOrder});
|
||||
@ -72,10 +74,8 @@ bool ColorOrderMap::add(uint16_t start, uint16_t len, uint8_t colorOrder) {
|
||||
uint8_t IRAM_ATTR ColorOrderMap::getPixelColorOrder(uint16_t pix, uint8_t defaultColorOrder) const {
|
||||
// upper nibble contains W swap information
|
||||
// when ColorOrderMap's upper nibble contains value >0 then swap information is used from it, otherwise global swap is used
|
||||
for (unsigned i = 0; i < count(); i++) {
|
||||
if (pix >= _mappings[i].start && pix < (_mappings[i].start + _mappings[i].len)) {
|
||||
return _mappings[i].colorOrder | ((_mappings[i].colorOrder >> 4) ? 0 : (defaultColorOrder & 0xF0));
|
||||
}
|
||||
for (const auto& map : _mappings) {
|
||||
if (pix >= map.start && pix < (map.start + map.len)) return map.colorOrder | ((map.colorOrder >> 4) ? 0 : (defaultColorOrder & 0xF0));
|
||||
}
|
||||
return defaultColorOrder;
|
||||
}
|
||||
@ -124,13 +124,12 @@ uint8_t *Bus::allocateData(size_t size) {
|
||||
}
|
||||
|
||||
|
||||
BusDigital::BusDigital(const BusConfig &bc, uint8_t nr, const ColorOrderMap &com)
|
||||
BusDigital::BusDigital(const BusConfig &bc, uint8_t nr)
|
||||
: Bus(bc.type, bc.start, bc.autoWhite, bc.count, bc.reversed, (bc.refreshReq || bc.type == TYPE_TM1814))
|
||||
, _skip(bc.skipAmount) //sacrificial pixels
|
||||
, _colorOrder(bc.colorOrder)
|
||||
, _milliAmpsPerLed(bc.milliAmpsPerLed)
|
||||
, _milliAmpsMax(bc.milliAmpsMax)
|
||||
, _colorOrderMap(com)
|
||||
{
|
||||
if (!isDigital(bc.type) || !bc.count) return;
|
||||
if (!PinManager::allocatePin(bc.pins[0], true, PinOwner::BusDigital)) return;
|
||||
@ -819,13 +818,17 @@ uint32_t BusManager::memUsage(unsigned maxChannels, unsigned maxCount, unsigned
|
||||
int BusManager::add(const BusConfig &bc) {
|
||||
if (getNumBusses() - getNumVirtualBusses() >= WLED_MAX_BUSSES) return -1;
|
||||
if (Bus::isVirtual(bc.type)) {
|
||||
busses[numBusses] = new BusNetwork(bc);
|
||||
busses.push_back(make_unique<BusNetwork>(bc));
|
||||
//busses.push_back(new BusNetwork(bc));
|
||||
} else if (Bus::isDigital(bc.type)) {
|
||||
busses[numBusses] = new BusDigital(bc, numBusses, colorOrderMap);
|
||||
busses.push_back(make_unique<BusDigital>(bc, numDigital));
|
||||
//busses.push_back(new BusDigital(bc, numDigital));
|
||||
} else if (Bus::isOnOff(bc.type)) {
|
||||
busses[numBusses] = new BusOnOff(bc);
|
||||
busses.push_back(make_unique<BusOnOff>(bc));
|
||||
//busses.push_back(new BusOnOff(bc));
|
||||
} else {
|
||||
busses[numBusses] = new BusPwm(bc);
|
||||
busses.push_back(make_unique<BusPwm>(bc));
|
||||
//busses.push_back(new BusPwm(bc));
|
||||
}
|
||||
return numBusses++;
|
||||
}
|
||||
@ -865,9 +868,8 @@ void BusManager::removeAll() {
|
||||
DEBUG_PRINTLN(F("Removing all."));
|
||||
//prevents crashes due to deleting busses while in use.
|
||||
while (!canAllShow()) yield();
|
||||
for (unsigned i = 0; i < numBusses; i++) delete busses[i];
|
||||
numBusses = 0;
|
||||
_parallelOutputs = 1;
|
||||
//for (auto &bus : busses) delete bus; // needed when not using std::unique_ptr C++ >11
|
||||
busses.clear();
|
||||
PolyBus::setParallelI2S1Output(false);
|
||||
}
|
||||
|
||||
@ -914,8 +916,8 @@ void BusManager::on() {
|
||||
uint8_t pins[2] = {255,255};
|
||||
if (busses[i]->isDigital() && busses[i]->getPins(pins)) {
|
||||
if (pins[0] == LED_BUILTIN || pins[1] == LED_BUILTIN) {
|
||||
BusDigital *bus = static_cast<BusDigital*>(busses[i]);
|
||||
bus->begin();
|
||||
BusDigital &b = static_cast<BusDigital&>(*bus);
|
||||
b.begin();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -943,16 +945,10 @@ void BusManager::off() {
|
||||
}
|
||||
|
||||
void BusManager::show() {
|
||||
_milliAmpsUsed = 0;
|
||||
for (unsigned i = 0; i < numBusses; i++) {
|
||||
busses[i]->show();
|
||||
_milliAmpsUsed += busses[i]->getUsedCurrent();
|
||||
}
|
||||
}
|
||||
|
||||
void BusManager::setStatusPixel(uint32_t c) {
|
||||
for (unsigned i = 0; i < numBusses; i++) {
|
||||
busses[i]->setStatusPixel(c);
|
||||
_gMilliAmpsUsed = 0;
|
||||
for (auto &bus : busses) {
|
||||
bus->show();
|
||||
_gMilliAmpsUsed += bus->getUsedCurrent();
|
||||
}
|
||||
}
|
||||
|
||||
@ -995,17 +991,8 @@ bool BusManager::canAllShow() {
|
||||
return true;
|
||||
}
|
||||
|
||||
Bus* BusManager::getBus(uint8_t busNr) {
|
||||
if (busNr >= numBusses) return nullptr;
|
||||
return busses[busNr];
|
||||
}
|
||||
ColorOrderMap& BusManager::getColorOrderMap() { return _colorOrderMap; }
|
||||
|
||||
//semi-duplicate of strip.getLengthTotal() (though that just returns strip._length, calculated in finalizeInit())
|
||||
uint16_t BusManager::getTotalLength() {
|
||||
unsigned len = 0;
|
||||
for (unsigned i=0; i<numBusses; i++) len += busses[i]->getLength();
|
||||
return len;
|
||||
}
|
||||
|
||||
bool PolyBus::useParallelI2S = false;
|
||||
|
||||
@ -1016,9 +1003,7 @@ uint8_t Bus::_gAWM = 255;
|
||||
|
||||
uint16_t BusDigital::_milliAmpsTotal = 0;
|
||||
|
||||
uint8_t BusManager::numBusses = 0;
|
||||
Bus* BusManager::busses[WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES];
|
||||
ColorOrderMap BusManager::colorOrderMap = {};
|
||||
uint16_t BusManager::_milliAmpsUsed = 0;
|
||||
uint16_t BusManager::_milliAmpsMax = ABL_MILLIAMPS_DEFAULT;
|
||||
uint8_t BusManager::_parallelOutputs = 1;
|
||||
std::vector<std::unique_ptr<Bus>> BusManager::busses;
|
||||
//std::vector<Bus*> BusManager::busses;
|
||||
uint16_t BusManager::_gMilliAmpsUsed = 0;
|
||||
uint16_t BusManager::_gMilliAmpsMax = ABL_MILLIAMPS_DEFAULT;
|
||||
|
@ -8,6 +8,20 @@
|
||||
#include "const.h"
|
||||
#include "pin_manager.h"
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <bits/unique_ptr.h>
|
||||
|
||||
#if __cplusplus >= 201402L
|
||||
using std::make_unique;
|
||||
#else
|
||||
// Really simple C++11 shim for non-array case; implementation from cppreference.com
|
||||
template<class T, class... Args>
|
||||
std::unique_ptr<T>
|
||||
make_unique(Args&&... args)
|
||||
{
|
||||
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
|
||||
}
|
||||
#endif
|
||||
|
||||
//colors.cpp
|
||||
uint16_t approximateKelvinFromRGB(uint32_t rgb);
|
||||
@ -198,7 +212,7 @@ class Bus {
|
||||
|
||||
class BusDigital : public Bus {
|
||||
public:
|
||||
BusDigital(const BusConfig &bc, uint8_t nr, const ColorOrderMap &com);
|
||||
BusDigital(const BusConfig &bc, uint8_t nr);
|
||||
~BusDigital() { cleanup(); }
|
||||
|
||||
void show() override;
|
||||
@ -229,7 +243,6 @@ class BusDigital : public Bus {
|
||||
uint8_t _milliAmpsPerLed;
|
||||
uint16_t _milliAmpsMax;
|
||||
void * _busPtr;
|
||||
const ColorOrderMap &_colorOrderMap;
|
||||
|
||||
static uint16_t _milliAmpsTotal; // is overwitten/recalculated on each show()
|
||||
|
||||
@ -374,61 +387,58 @@ struct BusConfig {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
class BusManager {
|
||||
public:
|
||||
BusManager() {};
|
||||
namespace BusManager {
|
||||
|
||||
//utility to get the approx. memory usage of a given BusConfig
|
||||
static uint32_t memUsage(const BusConfig &bc);
|
||||
static uint32_t memUsage(unsigned channels, unsigned count, unsigned buses = 1);
|
||||
static uint16_t currentMilliamps() { return _milliAmpsUsed + MA_FOR_ESP; }
|
||||
static uint16_t ablMilliampsMax() { return _milliAmpsMax; }
|
||||
extern std::vector<std::unique_ptr<Bus>> busses;
|
||||
//extern std::vector<Bus*> busses;
|
||||
extern uint16_t _gMilliAmpsUsed;
|
||||
extern uint16_t _gMilliAmpsMax;
|
||||
|
||||
static int add(const BusConfig &bc);
|
||||
static void useParallelOutput(); // workaround for inaccessible PolyBus
|
||||
#ifdef ESP32_DATA_IDLE_HIGH
|
||||
void esp32RMTInvertIdle() ;
|
||||
#endif
|
||||
inline uint8_t getNumVirtualBusses() {
|
||||
int j = 0;
|
||||
for (const auto &bus : busses) j += bus->isVirtual();
|
||||
return j;
|
||||
}
|
||||
|
||||
//do not call this method from system context (network callback)
|
||||
static void removeAll();
|
||||
unsigned memUsage();
|
||||
inline uint16_t currentMilliamps() { return _gMilliAmpsUsed + MA_FOR_ESP; }
|
||||
//inline uint16_t ablMilliampsMax() { unsigned sum = 0; for (auto &bus : busses) sum += bus->getMaxCurrent(); return sum; }
|
||||
inline uint16_t ablMilliampsMax() { return _gMilliAmpsMax; } // used for compatibility reasons (and enabling virtual global ABL)
|
||||
inline void setMilliampsMax(uint16_t max) { _gMilliAmpsMax = max;}
|
||||
|
||||
static void on();
|
||||
static void off();
|
||||
void useParallelOutput(); // workaround for inaccessible PolyBus
|
||||
bool hasParallelOutput(); // workaround for inaccessible PolyBus
|
||||
|
||||
static void show();
|
||||
static bool canAllShow();
|
||||
static void setStatusPixel(uint32_t c);
|
||||
[[gnu::hot]] static void setPixelColor(unsigned pix, uint32_t c);
|
||||
static void setBrightness(uint8_t b);
|
||||
// for setSegmentCCT(), cct can only be in [-1,255] range; allowWBCorrection will convert it to K
|
||||
// WARNING: setSegmentCCT() is a misleading name!!! much better would be setGlobalCCT() or just setCCT()
|
||||
static void setSegmentCCT(int16_t cct, bool allowWBCorrection = false);
|
||||
static inline void setMilliampsMax(uint16_t max) { _milliAmpsMax = max;}
|
||||
[[gnu::hot]] static uint32_t getPixelColor(unsigned pix);
|
||||
static inline int16_t getSegmentCCT() { return Bus::getCCT(); }
|
||||
//do not call this method from system context (network callback)
|
||||
void removeAll();
|
||||
int add(const BusConfig &bc);
|
||||
|
||||
static Bus* getBus(uint8_t busNr);
|
||||
void on();
|
||||
void off();
|
||||
|
||||
//semi-duplicate of strip.getLengthTotal() (though that just returns strip._length, calculated in finalizeInit())
|
||||
static uint16_t getTotalLength();
|
||||
static inline uint8_t getNumBusses() { return numBusses; }
|
||||
static String getLEDTypesJSONString();
|
||||
[[gnu::hot]] void setPixelColor(unsigned pix, uint32_t c);
|
||||
[[gnu::hot]] uint32_t getPixelColor(unsigned pix);
|
||||
void show();
|
||||
bool canAllShow();
|
||||
inline void setStatusPixel(uint32_t c) { for (auto &bus : busses) bus->setStatusPixel(c);}
|
||||
inline void setBrightness(uint8_t b) { for (auto &bus : busses) bus->setBrightness(b); }
|
||||
// for setSegmentCCT(), cct can only be in [-1,255] range; allowWBCorrection will convert it to K
|
||||
// WARNING: setSegmentCCT() is a misleading name!!! much better would be setGlobalCCT() or just setCCT()
|
||||
void setSegmentCCT(int16_t cct, bool allowWBCorrection = false);
|
||||
inline int16_t getSegmentCCT() { return Bus::getCCT(); }
|
||||
inline Bus& getBus(uint8_t busNr) { return *busses[std::min((size_t)busNr, busses.size()-1)]; }
|
||||
inline uint8_t getNumBusses() { return busses.size(); }
|
||||
|
||||
static inline ColorOrderMap& getColorOrderMap() { return colorOrderMap; }
|
||||
|
||||
private:
|
||||
static uint8_t numBusses;
|
||||
static Bus* busses[WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES];
|
||||
static ColorOrderMap colorOrderMap;
|
||||
static uint16_t _milliAmpsUsed;
|
||||
static uint16_t _milliAmpsMax;
|
||||
static uint8_t _parallelOutputs;
|
||||
|
||||
#ifdef ESP32_DATA_IDLE_HIGH
|
||||
static void esp32RMTInvertIdle() ;
|
||||
#endif
|
||||
static uint8_t getNumVirtualBusses() {
|
||||
int j = 0;
|
||||
for (int i=0; i<numBusses; i++) if (busses[i]->isVirtual()) j++;
|
||||
return j;
|
||||
}
|
||||
//semi-duplicate of strip.getLengthTotal() (though that just returns strip._length, calculated in finalizeInit())
|
||||
inline uint16_t getTotalLength(bool onlyPhysical = false) {
|
||||
unsigned len = 0;
|
||||
for (const auto &bus : busses) if (!(bus->isVirtual() && onlyPhysical)) len += bus->getLength();
|
||||
return len;
|
||||
}
|
||||
String getLEDTypesJSONString();
|
||||
ColorOrderMap& getColorOrderMap();
|
||||
};
|
||||
#endif
|
||||
|
@ -876,8 +876,7 @@ void serializeConfig() {
|
||||
const ColorOrderMap& com = BusManager::getColorOrderMap();
|
||||
for (size_t s = 0; s < com.count(); s++) {
|
||||
const ColorOrderMapEntry *entry = com.get(s);
|
||||
if (!entry) break;
|
||||
|
||||
if (!entry || !entry->len) break;
|
||||
JsonObject co = hw_com.createNestedObject();
|
||||
co["start"] = entry->start;
|
||||
co["len"] = entry->len;
|
||||
|
@ -208,8 +208,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
type |= request->hasArg(rf) << 7; // off refresh override
|
||||
// actual finalization is done in WLED::loop() (removing old busses and adding new)
|
||||
// this may happen even before this loop is finished so we do "doInitBusses" after the loop
|
||||
if (busConfigs[s] != nullptr) delete busConfigs[s];
|
||||
busConfigs[s] = new(std::nothrow) BusConfig(type, pins, start, length, colorOrder | (channelSwap<<4), request->hasArg(cv), skip, awmode, freq, useGlobalLedBuffer, maPerLed, maMax);
|
||||
busConfigs.emplace_back(type, pins, start, length, colorOrder | (channelSwap<<4), request->hasArg(cv), skip, awmode, freq, useGlobalLedBuffer, maPerLed, maMax);
|
||||
busesChanged = true;
|
||||
}
|
||||
//doInitBusses = busesChanged; // we will do that below to ensure all input data is processed
|
||||
|
@ -891,12 +891,11 @@ WLED_GLOBAL ESPAsyncE131 ddp _INIT_N(((handleE131Packet)));
|
||||
WLED_GLOBAL bool e131NewData _INIT(false);
|
||||
|
||||
// led fx library object
|
||||
WLED_GLOBAL BusManager busses _INIT(BusManager());
|
||||
WLED_GLOBAL WS2812FX strip _INIT(WS2812FX());
|
||||
WLED_GLOBAL BusConfig* busConfigs[WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES] _INIT({nullptr}); //temporary, to remember values from network callback until after
|
||||
WLED_GLOBAL bool doInitBusses _INIT(false);
|
||||
WLED_GLOBAL int8_t loadLedmap _INIT(-1);
|
||||
WLED_GLOBAL uint8_t currentLedmap _INIT(0);
|
||||
WLED_GLOBAL WS2812FX strip _INIT(WS2812FX());
|
||||
WLED_GLOBAL std::vector<BusConfig> busConfigs; //temporary, to remember values from network callback until after
|
||||
WLED_GLOBAL bool doInitBusses _INIT(false);
|
||||
WLED_GLOBAL int8_t loadLedmap _INIT(-1);
|
||||
WLED_GLOBAL uint8_t currentLedmap _INIT(0);
|
||||
#ifndef ESP8266
|
||||
WLED_GLOBAL char *ledmapNames[WLED_MAX_LEDMAPS-1] _INIT_N(({nullptr}));
|
||||
#endif
|
||||
|
@ -357,7 +357,7 @@ void getSettingsJS(byte subPage, Print& settingsScript)
|
||||
const ColorOrderMap& com = BusManager::getColorOrderMap();
|
||||
for (int s = 0; s < com.count(); s++) {
|
||||
const ColorOrderMapEntry* entry = com.get(s);
|
||||
if (entry == nullptr) break;
|
||||
if (!entry || !entry->len) break;
|
||||
settingsScript.printf_P(PSTR("addCOM(%d,%d,%d);"), entry->start, entry->len, entry->colorOrder);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user