mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2025-02-22 00:36:04 +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 <DCCTimer.h>
|
||||||
#include <DccMQTT.h>
|
#include <DccMQTT.h>
|
||||||
#include <Queue.h>
|
#include <Queue.h>
|
||||||
|
#include <ObjectPool.h>
|
||||||
|
|
||||||
//---------
|
//---------
|
||||||
// Variables
|
// Variables
|
||||||
//---------
|
//---------
|
||||||
|
|
||||||
|
DccMQTT DccMQTT::singleton;
|
||||||
|
auto mqtt = DccMQTT::get();
|
||||||
|
|
||||||
char topicName[MAXTBUF];
|
char topicName[MAXTBUF];
|
||||||
char topicMessage[MAXTMSG];
|
char topicMessage[MAXTMSG];
|
||||||
// char keyword[MAX_KEYWORD_LENGTH];
|
// 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
|
* @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';
|
topicName[0] = '\0';
|
||||||
topicMessage[0] = '\0';
|
topicMessage[0] = '\0';
|
||||||
strcpy(topicName, topic);
|
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 <Queue.h>
|
||||||
#include <Ethernet.h>
|
#include <Ethernet.h>
|
||||||
#include <Dns.h>
|
#include <Dns.h>
|
||||||
|
#include <ObjectPool.h>
|
||||||
|
|
||||||
#define MAXPAYLOAD 64
|
#define MAXPAYLOAD 64
|
||||||
#define MAXDOMAINLENGTH 32
|
#define MAXDOMAINLENGTH 32
|
||||||
@ -78,10 +79,9 @@ struct MQTTBroker
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DccMQTTMsg
|
typedef struct csmsg_t {
|
||||||
{
|
char cmd[MAXPAYLOAD];
|
||||||
char payload[MAXPAYLOAD];
|
} csmsg_t;
|
||||||
};
|
|
||||||
|
|
||||||
enum DccMQTTState
|
enum DccMQTTState
|
||||||
{
|
{
|
||||||
@ -107,8 +107,9 @@ private:
|
|||||||
PubSubClient mqttClient; // PubSub Endpoint for data exchange
|
PubSubClient mqttClient; // PubSub Endpoint for data exchange
|
||||||
MQTTBroker *broker; // Broker configuration object as set in config.h
|
MQTTBroker *broker; // Broker configuration object as set in config.h
|
||||||
|
|
||||||
Queue<DccMQTTMsg> in;
|
ObjectPool<csmsg_t,MAXPOOLSIZE> pool;
|
||||||
Queue<DccMQTTMsg> out;
|
Queue<int> in;
|
||||||
|
Queue<int> out;
|
||||||
|
|
||||||
char clientID[(CLIENTIDSIZE*2)+1];
|
char clientID[(CLIENTIDSIZE*2)+1];
|
||||||
|
|
||||||
@ -124,6 +125,11 @@ public:
|
|||||||
bool isConnected() { return mqState == CONNECTED; };
|
bool isConnected() { return mqState == CONNECTED; };
|
||||||
void setState(DccMQTTState s) { mqState = s; };
|
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 setup(); // called at setup in the main ino file
|
||||||
void loop();
|
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