Compare commits

...

6 Commits
tls ... master

Author SHA1 Message Date
Brad Arant
b5f4947f7c minor format change, 2025-06-05 16:54:36 +00:00
Brad Arant
1d16d0c17f merge conflicts resolution with develop->master. 2025-06-05 16:07:50 +00:00
Brad Arant
4230734ee6 Remove intellisense work files. 2025-06-05 16:03:53 +00:00
Brad Arant
57f47fdecb Convert Subscription and SubscriptionManager to MString. 2023-10-26 18:28:51 -07:00
Matt Arant
3a75e920d9 Servercore Changes 2023-10-06 18:31:22 +00:00
Brad
9a39b6224c *NEXT/*DIE 2023-06-19 23:22:46 +00:00
15 changed files with 289 additions and 242 deletions

View File

@ -1,14 +1,17 @@
#include "Command.h"
#include "Log.h"
#include "CommandList.h"
#include "Log.h"
namespace core {
namespace core
{
int Command::processCommand(coreutils::ZString &request, TCPSession &session) {
int Command::processCommand(coreutils::ZString &request, TCPSession &session)
{
return 0;
}
void Command::output(std::stringstream &out) {
void Command::output(std::stringstream &out)
{
out << "Write your own command description here for the help system." << std::endl;
}

View File

@ -1,12 +1,13 @@
#ifndef __Command_h__
#define __Command_h__
#include "includes"
#include "Object.h"
#include "TCPSession.h"
#include "ZString.h"
#include "includes"
namespace core {
namespace core
{
class CommandList;
@ -19,10 +20,10 @@ namespace core {
/// a list of functions that can be invoked as a result of processing a request.
///
class Command {
public:
class Command
{
public:
///
/// This method is used to implement the functionality of the requested command.
/// This pure virtual function must be implemented in your inheriting object.
@ -43,7 +44,6 @@ namespace core {
///
virtual void output(std::stringstream &out);
};
}

View File

@ -99,13 +99,11 @@ namespace core
return !shutDown;
}
void Socket::onDataReceived(std::string data)
{
void Socket::onDataReceived(std::string data) {
throw coreutils::Exception("Need to override onDataReceived.", __FILE__, __LINE__, -1);
}
void Socket::onDataReceived(coreutils::ZString &data)
{
void Socket::onDataReceived(coreutils::ZString &data) {
onDataReceived(std::string(data.getData(), data.getLength()));
}

View File

@ -1,23 +1,29 @@
#include "Subscription.h"
#include "Log.h"
#include "MString.h"
#include "TCPSession.h"
#include "TCPSocket.h"
#include <algorithm>
namespace core {
Subscription::Subscription(std::string id, std::string mode)
: id(id), mode(mode), owner(NULL), handler(NULL) {}
Subscription::Subscription(coreutils::MString id, coreutils::MString mode)
: id(id), mode(mode), owner(""), handler(NULL) {}
Subscription::Subscription(std::string id, TCPSession &session, std::string mode)
: id(id), mode(mode), owner(&session), handler(NULL) {}
Subscription::Subscription(coreutils::MString id, coreutils::MString owner, coreutils::MString mode)
: id(id), mode(mode), owner(owner), handler(NULL) {}
Subscription::Subscription(std::string id, TCPSession &session, std::string mode, SubscriptionHandler *handler)
: id(id), mode(mode), owner(&session), handler(handler) {
// coreutils::Log(coreutils::LOG_DEBUG_3) << "Subscription '" << id << "' with handler '" << handler->name << "'";
}
Subscription::Subscription(coreutils::MString id, coreutils::MString owner, coreutils::MString ownership, coreutils::MString mode, SubscriptionHandler *handler, coreutils::MString will, coreutils::MString timer)
: id(id), ownership(ownership), mode(mode), owner(owner), handler(handler), will(will), timer(timer) {
coreutils::Log(coreutils::LOG_DEBUG_3) << owner;
coreutils::Log(coreutils::LOG_DEBUG_3) << will;
subscriptionOwner(owner, will);
}
Subscription::~Subscription() {
std::stringstream out;
out << "cancel:" << id << std::endl;
for (auto subscriber : subscribers) {
subscriber->write(out.str());
@ -26,24 +32,30 @@ namespace core {
int Subscription::subscribe(TCPSession &session) {
if (handler)
handler->onSubscribe(session, this);
handler->onSubscribe(session, this);
else
onSubscribe(session);
onSubscribe(session);
subscribers.push_back(&session);
return 1;
}
int Subscription::unsubscribe(TCPSession &session) {
for (auto subscriber = subscribers.begin(); subscriber < subscribers.end(); ++subscriber) {
if (*subscriber == &session) {
subscribers.erase(subscriber++);
return 1;
}
}
for (auto subscriber = subscribers.begin(); subscriber < subscribers.end(); ++subscriber)
if (*subscriber == &session) {
subscribers.erase(subscriber++);
return 1;
}
return 0;
}
bool Subscription::subscriptionOwner(coreutils::MString alias, coreutils::MString ownerSelection) {
subscriptionOwners = alias;
selectionOfOwnerForSubscription = ownerSelection;
coreutils::Log(coreutils::LOG_DEBUG_1) << "Owner of Subscription: " << subscriptionOwners;
coreutils::Log(coreutils::LOG_DEBUG_1) << "Will of Subscription: " << selectionOfOwnerForSubscription;
return true;
}
int Subscription::process(coreutils::ZString &request, std::stringstream &out, TCPSession &session) {
if (handler)
handler->process(request, out, session, this);
@ -54,7 +66,7 @@ namespace core {
int Subscription::event(std::stringstream &out) {
for (auto subscriber = subscribers.begin(); subscriber < subscribers.end(); ++subscriber)
(*subscriber)->write(out.str());
(*subscriber)->write(out.str());
return 1;
}
@ -72,10 +84,9 @@ namespace core {
void Subscription::sendToAll(std::stringstream &data, TCPSession &sender) {
for (auto session : subscribers)
if (session != &sender)
session->write(data.str());
if (session != &sender)
session->write(data.str());
data.str("");
}
}

View File

@ -1,23 +1,23 @@
#ifndef __Subscription_h__
#define __Subscription_h__
#include "SubscriptionHandler.h"
#include "MString.h"
#include "SessionFilter.h"
#include "SubscriptionHandler.h"
#include "ZString.h"
#include <string>
#include <vector>
namespace core
{
namespace core {
class TCPSession;
class Subscription {
public:
Subscription(std::string id, std::string mode = "*AUTHOR");
Subscription(std::string id, TCPSession &session, std::string mode);
Subscription(std::string id, TCPSession &session, std::string mode, SubscriptionHandler *handler);
public:
Subscription(coreutils::MString id, coreutils::MString mode = "*AUTHOR");
Subscription(coreutils::MString id, coreutils::MString owner, coreutils::MString mode);
Subscription(coreutils::MString id, coreutils::MString owner, coreutils::MString ownership, coreutils::MString mode, SubscriptionHandler *handler, coreutils::MString selection, coreutils::MString time);
virtual ~Subscription();
int subscribe(TCPSession &session);
@ -28,7 +28,7 @@ namespace core
virtual int onSubscribe(TCPSession &session);
int event(std::stringstream &out);
bool subscriptionOwner(coreutils::MString owner, coreutils::MString selection);
bool ifSubscriber(TCPSession &session);
bool subInvite(TCPSession &session);
@ -36,13 +36,18 @@ namespace core
void sendToAll(std::stringstream &data, TCPSession &sender);
void sendToAll(std::stringstream &data, TCPSession &sender, SessionFilter filter);
std::string id;
std::string mode;
TCPSession *owner;
coreutils::MString id;
coreutils::MString mode;
coreutils::MString owner;
coreutils::MString subscriptionOwners;
coreutils::MString selectionOfOwnerForSubscription;
coreutils::MString will;
coreutils::MString ownership;
coreutils::MString timer;
SubscriptionHandler *handler;
std::vector<TCPSession *> subscribers;
};
}

View File

@ -1,9 +1,9 @@
#include "SubscriptionManager.h"
#include "Log.h"
#include "Subscription.h"
#include "SubscriptionHandlerFactory.h"
#include "TCPServer.h"
#include <algorithm>
#include "SubscriptionHandlerFactory.h"
namespace core {
@ -14,29 +14,51 @@ namespace core {
return 1;
}
bool SubscriptionManager::onClearSubscription(coreutils::MString temp, coreutils::MString key) {
temp = "";
key = "";
return true;
}
int SubscriptionManager::removeSessionSubscriptions(TCPSession &session) {
int countSubscribed = 0;
int countPublished = 0;
int count = 0;
lock.lock();
std::string temp = "";
for (auto [key, subscription] : subscriptions)
{
if (temp != "")
{
coreutils::MString temp = "";
for (auto [key, subscription] : subscriptions) {
if (temp != "") {
subscriptions.erase(temp);
temp = "";
}
countSubscribed += subscription->unsubscribe(session);
if (subscription->owner == &session)
{
temp = key;
delete subscription;
if (subscription->subscriptionOwners == session.alias) {
if (subscription->selectionOfOwnerForSubscription == "*DIE") {
onClearSubscription(temp, key);
}
else if (subscription->will == "*NEXT") {
if (subscription->subscribers.size() < 1) {
coreutils::Log(coreutils::LOG_DEBUG_1) << "There is not enough people to move to the next";
onClearSubscription(temp, key);
}
else {
for (auto subscribed = subscription->subscribers.begin(); subscribed < subscription->subscribers.end(); subscribed++) {
if ((*subscribed)->alias == session.alias) {
subscription->subscribers.erase(subscribed++);
}
subscription->subscriptionOwner(session.alias, "*NEXT");
}
}
}
else {
coreutils::Log(coreutils::LOG_DEBUG_1) << "Subscription doesn't exist";
}
++countPublished;
}
}
if (temp != "")
{
if (temp != "") {
subscriptions.erase(temp);
temp = "";
}
@ -47,29 +69,34 @@ namespace core {
}
int SubscriptionManager::processCommand(coreutils::ZString &request, TCPSession &session) {
if (request[0].equals("publish")) {
if (request[0] == "publish") {
SubscriptionHandler *handler = NULL;
if(request.getList().size() > 3) {
factory->getSubscriptionHandler(request[3].str());
if (request.getList().size() > 3) {
handler = factory->getSubscriptionHandler(request[4].str());
}
newSubscription = new Subscription(request[1].str(), session, request[2].str(), handler);
subscriptions.insert(std::make_pair(request[1].str(), newSubscription));
newSubscription->owner = &session;
if (request[2] == "*OWNER") {
newSubscription = new Subscription(request[1].str(), session.alias, request[2].str(), request[3].str(), handler, request[5].str(), request[6].str());
subscriptions.insert(std::make_pair(request[1].str(), newSubscription));
return 1;
}
return 1;
} else if (request[0].equals("catalog")) {
}
else if (request[0] == "catalog") {
session.out << ":catalog:";
for (auto const &[key, subscription] : subscriptions) {
session.out << subscription->id << ";";
}
session.out << std::endl;
return 1;
} else if (request[0].equals("invite")) {
}
else if (request[0] == "invite") {
std::stringstream out;
coreutils::Log(coreutils::LOG_DEBUG_1) << request[2];
std::string invitee = request[2].str();
TCPSession *tempSession = session.server.getSessionByAlias(&invitee);
invitee = (coreutils::MString *)&request[2];
TCPSession *tempSession = session.server.getSessionByAlias(invitee);
std::stringstream temp;
temp << "invite:" << request[1] << ":" << *(std::string *)session.alias;
temp << "invite:" << request[1] << ":" << invitee;
tempSession->write(temp.str());
return 1;
}
@ -77,30 +104,29 @@ namespace core {
auto subscription = subscriptions[request[1].str()];
if (request[1].equals(subscription->id)) {
if (request[0].equals("unpublish")) {
if (request[0] == "unpublish") {
subscriptions.erase(request[1].str());
} else if (request[0].equals("subscribe")) {
}
else if (request[0] == "subscribe") {
subscription->subscribe(session);
return 1;
} else if (request[0].equals("unsubscribe")) {
}
else if (request[0] == "unsubscribe") {
subscription->unsubscribe(session);
return 1;
} else if (request[0].equals("event")) {
}
else if (request[0] == "event") {
std::stringstream out;
subscription->process(request, out, session);
if (subscription->mode == "*ANYONE") {
subscription->event(out);
return 1;
} else if (subscription->mode == "*SUBSCRIBERS") {
}
else if (subscription->mode == "*SUBSCRIBERS") {
if (subscription->ifSubscriber(session)) {
subscription->event(out);
return 1;
}
} else if (subscription->mode == "*AUTHOR") {
if (subscription->owner == &session) {
subscription->event(out);
return 1;
}
}
}
return 0;

View File

@ -2,33 +2,40 @@
#define __SubscriptionManager_h__
#include "Command.h"
#include "MString.h"
#include "SessionFilter.h"
#include "Subscription.h"
#include "SubscriptionHandler.h"
#include "TCPSession.h"
#include "ZString.h"
#include <string>
#include <vector>
namespace core {
class SubscriptionHandlerFactory;
//*AUTHOR -> Dies when player disconnects
//*ANYONE -> Does not die when player disconnects
//*SUBSCRIPTION -> Does not die when player disconnects
//*OWNER -> Does die and transfers Ownership before he does
class SubscriptionManager : public Command {
class SubscriptionHandlerFactory;
public:
class SubscriptionManager : public Command {
int add(Subscription &subscription);
int removeSessionSubscriptions(TCPSession &session);
int processCommand(coreutils::ZString &request, TCPSession &session) override;
public:
int add(Subscription &subscription);
int removeSessionSubscriptions(TCPSession &session);
int processCommand(coreutils::ZString &request, TCPSession &session) override;
bool onClearSubscription(coreutils::MString temp, coreutils::MString key);
SubscriptionHandlerFactory *factory = NULL;
SubscriptionHandlerFactory *factory = NULL;
private:
Subscription *subscription;
std::map<coreutils::MString, Subscription *> subscriptions;
Subscription *newSubscription;
std::mutex lock;
coreutils::MString invitee;
private:
Subscription *subscription;
std::map<std::string, Subscription *> subscriptions;
Subscription *newSubscription;
std::mutex lock;
};
};
}

View File

@ -8,7 +8,8 @@ namespace core
{
TCPServer::TCPServer(EPoll &ePoll, IPAddress address, std::string delimiter, int depth, std::string text)
: TCPSocket(ePoll, text), commands(delimiter, depth) {
: TCPSocket(ePoll, text), commands(delimiter, depth)
{
commands.add(subscriptions, "publish");
commands.add(subscriptions, "unpublish");
@ -35,7 +36,8 @@ namespace core
close(getDescriptor());
}
void TCPServer::onDataReceived(std::string data) {
void TCPServer::onDataReceived(std::string data)
{
lock.lock();
TCPSession *session = accept();
if (session)
@ -43,9 +45,11 @@ namespace core
lock.unlock();
}
TCPSession * TCPServer::accept() {
TCPSession *TCPServer::accept()
{
try {
try
{
TCPSession *session = getSocketAccept(ePoll);
session->setDescriptor(::accept(getDescriptor(), (struct sockaddr *)&session->ipAddress.addr, &session->ipAddress.addressLength));
@ -72,30 +76,36 @@ namespace core
return NULL;
}
void TCPServer::removeFromSessionList(TCPSession *session) {
void TCPServer::removeFromSessionList(TCPSession *session)
{
std::vector<TCPSession *>::iterator cursor;
lock.lock();
for(cursor = sessions.begin(); cursor < sessions.end(); ++cursor)
if(*cursor == session) {
sessions.erase(cursor);
break;
}
for (cursor = sessions.begin(); cursor < sessions.end(); ++cursor)
if (*cursor == session)
{
sessions.erase(cursor);
break;
}
lock.unlock();
}
void TCPServer::sessionErrorHandler(std::string errorString, std::stringstream &out) {
void TCPServer::sessionErrorHandler(std::string errorString, std::stringstream &out)
{
throw coreutils::Exception(errorString);
}
TCPSession * TCPServer::getSocketAccept(EPoll &ePoll) {
TCPSession *TCPServer::getSocketAccept(EPoll &ePoll)
{
return new TCPSession(ePoll, *this);
}
void TCPServer::output(std::stringstream &out) {
void TCPServer::output(std::stringstream &out)
{
out << "Use the 'help' command to list the commands for this server." << std::endl;
}
int TCPServer::processCommand(coreutils::ZString &request, TCPSession &session) {
int TCPServer::processCommand(coreutils::ZString &request, TCPSession &session)
{
int sequence = 0;
for (auto *sessionx : sessions)
{
@ -130,12 +140,10 @@ namespace core
data.str("");
}
TCPSession *TCPServer::getSessionByAlias(void *alias)
{
coreutils::Log(coreutils::LOG_DEBUG_1) << alias;
TCPSession *TCPServer::getSessionByAlias(coreutils::MString alias) {
for (auto session : sessions)
if (session->compareAlias(alias))
return session;
if (session->alias == alias)
return session;
return NULL;
}

View File

@ -122,7 +122,7 @@ namespace core
/// of the alias pointer.
///
TCPSession *getSessionByAlias(void *alias);
TCPSession *getSessionByAlias(coreutils::MString alias);
protected:
///

View File

@ -7,49 +7,36 @@
namespace core
{
TCPSession::TCPSession(EPoll &ePoll, TCPServer &server, std::string text) : TCPSocket(ePoll, text), server(server)
{
uuid_t uuidObject;
uuid_generate(uuidObject);
coreutils::Log(coreutils::LOG_DEBUG_1) << uuidObject;
alias = (void *)uuidObject;
TCPSession::TCPSession(EPoll &ePoll, TCPServer &server, std::string text) : TCPSocket(ePoll, text), server(server) {
uuid_t uuid;
uuid_generate(uuid);
alias = coreutils::MString((char *)uuid, 26);
}
TCPSession::~TCPSession()
{
TCPSession::~TCPSession() {
server.removeFromSessionList(this);
server.subscriptions.removeSessionSubscriptions(*this);
}
void TCPSession::output(std::stringstream &data)
{
void TCPSession::output(std::stringstream &data) {
data << "|" << ipAddress.getClientAddressAndPort();
}
void TCPSession::protocol(coreutils::ZString &data)
{
void TCPSession::protocol(coreutils::ZString &data) {
if (data.getLength() != 0)
{
if (!server.commands.processRequest(data, *this))
{
coreutils::Log(coreutils::LOG_DEBUG_1) << "Received data could not be parsed: " << data.str();
}
}
if (!server.commands.processRequest(data, *this))
coreutils::Log(coreutils::LOG_DEBUG_1) << "Received data could not be parsed: " << data.str();
}
bool TCPSession::compareAlias(void *alias) {
return this->alias = alias;
}
void TCPSession::outputAlias(std::stringstream &out) {
out << alias;
}
// bool TCPSession::compareAlias(coreutils::MString alias) {
// return this->alias == alias;
// }
void TCPSession::onRegistered() {
onConnected();
send();
if (term)
shutdown("termination requested");
shutdown("termination requested");
}
void TCPSession::onConnected() {}
@ -75,8 +62,7 @@ namespace core
memmove(lineBuffer, lineBuffer + lineLength, lineBufferSize);
lineBuffer = (char *)realloc(lineBuffer, lineBufferSize);
}
else if (lineBufferSize >= blockLength)
{
else if (lineBufferSize >= blockLength) {
coreutils::ZString zBlock(lineBuffer, blockLength);
onBlockReceived(zBlock);
lineBufferSize -= blockLength;
@ -88,34 +74,30 @@ namespace core
}
}
void TCPSession::setBlockSize(int blockSize)
{
void TCPSession::setBlockSize(int blockSize) {
this->blockSize = blockSize;
}
void TCPSession::onLineReceived(coreutils::ZString &line)
{
void TCPSession::onLineReceived(coreutils::ZString &line) {
protocol(line);
send();
if (term)
shutdown("termination requested");
}
void TCPSession::onBlockReceived(coreutils::ZString &block)
{
void TCPSession::onBlockReceived(coreutils::ZString &block) {
coreutils::Log(coreutils::LOG_DEBUG_3) << "[" << block.getLength() << "]";
if (term)
shutdown("termination requested");
}
void TCPSession::send() {
if(out.tellp() > 0)
write(out.str());
if (out.tellp() > 0)
write(out.str());
out.str("");
}
void TCPSession::terminate()
{
void TCPSession::terminate() {
term = true;
}

View File

@ -1,9 +1,9 @@
#ifndef __Session_h__
#define __Session_h__
#include "MString.h"
#include "SessionFilter.h"
#include "TCPSocket.h"
namespace core
{
@ -76,20 +76,20 @@ namespace core
char uuid[37];
///
/// alias is a void pointer that can be set to point to any object that identifies
/// this session uniquely. Using this approach, inheriting objects can determine
/// how it knows the contacts that this server manages.
/// alias is a MString that can be set to any string of characters that identifies
/// this session uniquely. Alias's should be unique between sessions.
///
void *alias;
coreutils::MString alias;
///
///
///
///
///
///
virtual bool compareAlias(void *alias);
virtual void outputAlias(std::stringstream &out);
// bool compareAlias(coreutils::MString alias);
protected:
///

View File

@ -1,11 +1,12 @@
#ifndef __TCPSocket_h__
#define __TCPSocket_h__
#include "includes"
#include "Socket.h"
#include "IPAddress.h"
#include "Socket.h"
#include "includes"
namespace core {
namespace core
{
///
/// TCPSocket
@ -17,10 +18,10 @@ namespace core {
/// synchronous data connection.
///
class TCPSocket : public Socket {
public:
class TCPSocket : public Socket
{
public:
TCPSocket(EPoll &ePoll);
TCPSocket(EPoll &ePoll, std::string text);
virtual ~TCPSocket();
@ -37,7 +38,6 @@ namespace core {
///
virtual void output(std::stringstream &out);
};
}

View File

@ -1,16 +1,20 @@
#include "Timer.h"
namespace core {
namespace core
{
Timer::Timer(EPoll &ePoll, double delay = 0.0f) : Socket(ePoll, "Timer") {
Timer::Timer(EPoll &ePoll, double delay = 0.0f) : Socket(ePoll, "Timer")
{
setDescriptor(timerfd_create(CLOCK_REALTIME, 0));
setTimer(delay);
}
Timer::~Timer() {
Timer::~Timer()
{
}
void Timer::setTimer(double delay) {
void Timer::setTimer(double delay)
{
double integer;
double fraction;
@ -27,10 +31,10 @@ namespace core {
timer.it_value.tv_nsec = (int)(fraction * 1000000000);
timerfd_settime(getDescriptor(), 0, &timer, NULL);
}
void Timer::clearTimer() {
void Timer::clearTimer()
{
struct itimerspec timer;
@ -42,19 +46,22 @@ namespace core {
timerfd_settime(getDescriptor(), 0, &timer, NULL);
}
double Timer::getElapsed() {
double Timer::getElapsed()
{
struct itimerspec timer;
timerfd_gettime(getDescriptor(), &timer);
double toTimeout = (double)((timer.it_value.tv_sec * 1000000000L) + timer.it_value.tv_nsec) / 1000000000L;
return delayValue - toTimeout;
}
void Timer::onDataReceived(std::string data) {
void Timer::onDataReceived(std::string data)
{
onTimeout();
}
double Timer::getEpoch() {
return (double)std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()).count() /1000000000L;
double Timer::getEpoch()
{
return (double)std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()).count() / 1000000000L;
}
}

86
Timer.h
View File

@ -1,65 +1,65 @@
#ifndef __Timer_h__
#define __Timer_h__
#include "Socket.h"
#include "EPoll.h"
#include "Socket.h"
namespace core {
namespace core
{
///
/// Timer
///
/// Set and trigger callback upon specified timeout.
///
/// The Timer is used to establish a timer using the timer socket
/// interface. It cannot be instantiated directly but must be extended.
///
///
/// Timer
///
/// Set and trigger callback upon specified timeout.
///
/// The Timer is used to establish a timer using the timer socket
/// interface. It cannot be instantiated directly but must be extended.
///
class Timer : Socket {
class Timer : Socket
{
public:
public:
Timer(EPoll &ePoll);
Timer(EPoll &ePoll, double delay);
~Timer();
Timer(EPoll &ePoll, double delay);
~Timer();
///
/// Use the setTimer() method to set the time out value for timer. Setting the timer
/// also starts the timer countdown. The clearTimer() method can be used to reset
/// the timer without triggering the onTimeout() callback.
///
/// @param delay the amount of time in seconds to wait before trigering the onTimeout function.
///
///
/// Use the setTimer() method to set the time out value for timer. Setting the timer
/// also starts the timer countdown. The clearTimer() method can be used to reset
/// the timer without triggering the onTimeout() callback.
///
/// @param delay the amount of time in seconds to wait before trigering the onTimeout function.
///
void setTimer(double delay);
void setTimer(double delay);
///
/// Use the clearTimer() to unset the timer and return the timer to an idle state.
///
///
/// Use the clearTimer() to unset the timer and return the timer to an idle state.
///
void clearTimer();
void clearTimer();
///
/// Use the getElapsed() method to obtain the amount of time that has elapsed since
/// the timer was set.
///
///
/// Use the getElapsed() method to obtain the amount of time that has elapsed since
/// the timer was set.
///
double getElapsed();
double getElapsed();
double getEpoch();
double getEpoch();
protected:
protected:
///
/// This method is called when the time out occurs.
///
///
/// This method is called when the time out occurs.
///
virtual void onTimeout() = 0;
virtual void onTimeout() = 0;
private:
void onDataReceived(std::string data) override;
double delayValue;
};
private:
void onDataReceived(std::string data) override;
double delayValue;
};
}

Binary file not shown.