mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2025-02-19 23:46:02 +01:00
Added ObjectPool
This commit is contained in:
parent
866833a19e
commit
c042240019
23
DccMQTT.cpp
23
DccMQTT.cpp
@ -37,16 +37,20 @@
|
||||
#include <DCCTimer.h>
|
||||
#include <DccMQTT.h>
|
||||
#include <Queue.h>
|
||||
#include <ObjectPool.h>
|
||||
|
||||
//---------
|
||||
// Variables
|
||||
//---------
|
||||
|
||||
DccMQTT DccMQTT::singleton;
|
||||
auto mqtt = DccMQTT::get();
|
||||
|
||||
char topicName[MAXTBUF];
|
||||
char topicMessage[MAXTMSG];
|
||||
// char keyword[MAX_KEYWORD_LENGTH];
|
||||
|
||||
DccMQTT DccMQTT::singleton;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Copies an byte array to a hex representation as string; used for generating the unique Arduino ID
|
||||
@ -73,8 +77,21 @@ void mqttCallback(char *topic, byte *payload, unsigned int length)
|
||||
topicName[0] = '\0';
|
||||
topicMessage[0] = '\0';
|
||||
strcpy(topicName, topic);
|
||||
strlcpy(topicMessage, (char *)payload, length + 1);
|
||||
DIAG(F("MQTT Message arrived [%s]: [%s]"), topicName, topicMessage);
|
||||
|
||||
auto pool = mqtt->getPool();
|
||||
auto q = mqtt->getIncomming();
|
||||
|
||||
csmsg_t tm;
|
||||
strlcpy(tm.cmd, (char *)payload, length + 1);
|
||||
// Add the recieved command to the pool
|
||||
int idx = pool->setItem(tm);
|
||||
if ( idx == -1) {
|
||||
DIAG(F("MQTT Command pool full. Could not handle recieved command."));
|
||||
return;
|
||||
}
|
||||
// Add the index of the pool item to the incomming queue
|
||||
q->push(idx);
|
||||
DIAG(F("MQTT Message arrived [%s]: [%s]"), topicName, tm.cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
|
18
DccMQTT.h
18
DccMQTT.h
@ -14,6 +14,7 @@
|
||||
#include <Queue.h>
|
||||
#include <Ethernet.h>
|
||||
#include <Dns.h>
|
||||
#include <ObjectPool.h>
|
||||
|
||||
#define MAXPAYLOAD 64
|
||||
#define MAXDOMAINLENGTH 32
|
||||
@ -78,10 +79,9 @@ struct MQTTBroker
|
||||
};
|
||||
};
|
||||
|
||||
struct DccMQTTMsg
|
||||
{
|
||||
char payload[MAXPAYLOAD];
|
||||
};
|
||||
typedef struct csmsg_t {
|
||||
char cmd[MAXPAYLOAD];
|
||||
} csmsg_t;
|
||||
|
||||
enum DccMQTTState
|
||||
{
|
||||
@ -107,8 +107,9 @@ private:
|
||||
PubSubClient mqttClient; // PubSub Endpoint for data exchange
|
||||
MQTTBroker *broker; // Broker configuration object as set in config.h
|
||||
|
||||
Queue<DccMQTTMsg> in;
|
||||
Queue<DccMQTTMsg> out;
|
||||
ObjectPool<csmsg_t,MAXPOOLSIZE> pool;
|
||||
Queue<int> in;
|
||||
Queue<int> out;
|
||||
|
||||
char clientID[(CLIENTIDSIZE*2)+1];
|
||||
|
||||
@ -124,6 +125,11 @@ public:
|
||||
bool isConnected() { return mqState == CONNECTED; };
|
||||
void setState(DccMQTTState s) { mqState = s; };
|
||||
|
||||
ObjectPool<csmsg_t,MAXPOOLSIZE> *getPool() { return &pool; };
|
||||
Queue<int> *getIncomming() { return ∈ };
|
||||
Queue<int> *getOutgoing() { return &out; };
|
||||
|
||||
|
||||
void setup(); // called at setup in the main ino file
|
||||
void loop();
|
||||
|
||||
|
91
ObjectPool.h
Normal file
91
ObjectPool.h
Normal file
@ -0,0 +1,91 @@
|
||||
#ifndef _ObjectPool_h_
|
||||
#define _ObjectPool_h_
|
||||
|
||||
#include <DIAG.h>
|
||||
|
||||
#define MAXPOOLSIZE 32
|
||||
|
||||
template <typename T, int length>
|
||||
class ObjectPool
|
||||
{
|
||||
|
||||
// just make sure that we don't create a pool eating up all memory @compiletime
|
||||
static_assert(length <= MAXPOOLSIZE);
|
||||
|
||||
struct item
|
||||
{
|
||||
T i;
|
||||
bool free = true; // boolean 1 free i.e. i can be reused; 0 occupied
|
||||
};
|
||||
|
||||
private:
|
||||
item p[length]; // MAXPOOLSIZE items of struct item
|
||||
const int size = length; // size of the pool
|
||||
|
||||
int findFreeIdx()
|
||||
{ // find the first free index or return -1 if there is none
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
if (p[i].free)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1; // if we are here there is no free slot available
|
||||
}
|
||||
|
||||
public:
|
||||
int setItem(T i)
|
||||
{ // add an item to the pool at a free slot
|
||||
int idx = findFreeIdx();
|
||||
if (idx != -1)
|
||||
{
|
||||
p[idx].i = i;
|
||||
p[idx].free = false;
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief returns the slot for an object to the pool i.e. frees the slot for reuse of the data member and
|
||||
* clears out the memory
|
||||
*
|
||||
* @param idx
|
||||
* @return true if the return is ok
|
||||
* @return false otherwise
|
||||
*/
|
||||
bool returnItem(int idx)
|
||||
{ // clear item at pool index idx
|
||||
if (idx > size)
|
||||
{ // can't return an item outside of the pool size; returns false;
|
||||
return false;
|
||||
}
|
||||
memset(&p[idx].i, 0, sizeof(T)); // clear out the memory but keep the allocation for reuse
|
||||
p[idx].free = true;
|
||||
return true; // set the free flag
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Obtain a pool item
|
||||
* @note This should only be used for debugging.
|
||||
* It allows to change actually the content of the pool item where this should only be allowed for the setItem method.
|
||||
* @param idx Index of the pool item to retrieve
|
||||
* @param state State of the pool item ( 1 available, 0 occupied)
|
||||
* @return T* returns the pointer to the pool item
|
||||
*/
|
||||
T *getItem(int idx, bool *state)
|
||||
{
|
||||
*state = p[idx].free;
|
||||
return &p[idx].i;
|
||||
}
|
||||
|
||||
int getSize()
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
ObjectPool() = default;
|
||||
~ObjectPool() = default;
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user