Files
Industrial_Emulator/lib/Core/Equipment/Equipment.h

221 lines
6.9 KiB
C++

/**
* @file Equipment.h
* @brief Defines the main Equipment class for the device emulator.
* @author Emmanuel Hernandez Cruz
* @date 2025-09-02
*
* This file contains the definition for the Equipment class, which acts as the
* central context for the State design pattern. It manages the current state
* of the device and holds all of its Modbus points.
*/
#ifndef Equipment_h
#define Equipment_h
#include <Arduino.h>
#include <map>
#include <string>
#include <vector>
#include "States/State_Standby.h"
// Forward Declarations
template<typename T> class State;
template<typename T> class Modbus_Point;
/**
* @class Equipment
* @brief The main class representing the emulated device.
*
* This class orchestrates the device's behavior. It holds a collection of all
* Modbus points and manages the device's current operational state (e.g.,
* Standby, Running) by delegating actions to a concrete State object.
*/
template<typename T>
class Equipment {
public:
/**
* @brief Constructs a new Equipment object.
* Initializes the device in the default initial state (Standby).
*/
Equipment();
Equipment(T* server);
/** @brief The main update loop for the equipment, called repeatedly. Delegates to the current state. */
void update();
/** @brief Delegates the enter state logic to the current state object. */
void enterState();
/** @brief Delegates the exit state logic to the current state object. */
void exitState();
/**
* @brief Sets a simple integer identifier for the current state.
* @param stateId The integer ID representing the state.
*/
void setState(int stateId);
/**
* @brief Gets the simple integer identifier for the current state.
* @return The integer ID of the state.
*/
int getState();
/**
* @brief Transitions the equipment to a new state.
* Handles exiting the old state, deleting it, and entering the new one.
* @param newState A pointer to the new State object. The Equipment takes ownership.
*/
void changeState(State<T>* newState);
/**
* @brief Adds a Modbus point to the equipment's internal map.
* @param description The unique string description used as a key.
* @param point A pointer to the Modbus_Point object.
*/
void addModbus_Point(const std::string& description, Modbus_Point<T>* point);
/**
* @brief Retrieves a Modbus point by its description.
* @param description The string key for the Modbus point.
* @return A pointer to the Modbus_Point object, or nullptr if not found.
*/
Modbus_Point<T>* getModbus_Point(const std::string& description);
/**
* @brief Sets the value of a specific Modbus point.
* @param description The string key for the Modbus point.
* @param value The value to set. Note: This float may be truncated or cast
* depending on the underlying point's `setValue` implementation.
*/
void setModbus_Point(const std::string& description, float value);
private:
State<T>* _state; /**< @brief Pointer to the current state object. */
std::map<std::string, Modbus_Point<T>*> _points;/**< @brief Map of all Modbus points, keyed by description. */
int _stateId; /**< @brief A simple integer identifier for the current state. */
T* _server;
};
template<typename T>
Equipment<T>::Equipment() : _server(nullptr) {
this->_state = new StandbyState<T>();
this->_state->enterState(this);
}
/**
* @brief Constructs a new Equipment object with a server instance.
* @param server Pointer to the Modbus server instance (e.g., ModbusIP, ModbusRTU).
*/
template<typename T>
Equipment<T>::Equipment(T* server)
: _server(server)
{
this->_state = new StandbyState<T>();
this->_state->enterState(this);
}
/**
* @brief The main update loop for the equipment.
*
* This method delegates the update logic to the current state object. If the
* state's update method returns a pointer to a new state, this method
* triggers a state transition.
*/
template<typename T>
void Equipment<T>::update() {
State<T>* newState = this->_state->update(this);
if (newState != nullptr) {
changeState(newState);
}
}
/**
* @brief Delegates the enter state logic to the current state object.
*/
template<typename T>
void Equipment<T>::enterState() {
this->_state->enterState(this);
}
/**
* @brief Delegates the exit state logic to the current state object.
*/
template<typename T>
void Equipment<T>::exitState() {
this->_state->exitState(this);
}
/**
* @brief Adds a Modbus point to the equipment's internal collections.
* The point is added to a map for quick lookup by description and to a
* vector for simple iteration.
* @param description The unique string description used as a key.
* @param point A pointer to the Modbus_Point object.
*/
template<typename T>
void Equipment<T>::addModbus_Point(const std::string& description, Modbus_Point<T>* point) {
this->_points[description] = point;
}
/**
* @brief Retrieves a Modbus point by its description.
* @param description The string key for the Modbus point.
* @return A pointer to the Modbus_Point object, or nullptr if not found.
*/
template<typename T>
Modbus_Point<T>* Equipment<T>::getModbus_Point(const std::string& description) {
auto it = this->_points.find(description);
if (it != this->_points.end()) {
return it->second;
}
return nullptr;
}
/**
* @brief Sets the value of a specific Modbus point.
* Finds the point by its description and calls its `setValue` method.
* @param description The string key for the Modbus point.
* @param value The value to set. This float is cast to an int before being passed.
*/
template<typename T>
void Equipment<T>::setModbus_Point(const std::string& description, float value) {
Modbus_Point<T>* point = getModbus_Point(description);
if (point != nullptr) {
point->setValue(value);
}
}
/**
* @brief Gets the simple integer identifier for the current state.
* @return The integer ID of the state.
*/
template<typename T>
int Equipment<T>::getState() {
return _stateId;
}
/**
* @brief Sets a simple integer identifier for the current state.
* @param stateId The integer ID representing the state.
*/
template<typename T>
void Equipment<T>::setState(int stateId) {
this->_stateId = stateId;
}
/**
* @brief Transitions the equipment to a new state.
*
* This method handles the full lifecycle of a state transition: it calls
* `exitState` on the current state, deletes the old state object to prevent
* memory leaks, assigns the new state, and finally calls `enterState` on the
* new state.
*
* @param newState A pointer to the new State object. The Equipment takes ownership.
*/
template<typename T>
void Equipment<T>::changeState(State<T>* newState) {
if (this->_state != nullptr) {
this->_state->exitState(this);
delete this->_state;
}
this->_state = newState;
if (this->_state != nullptr) {
this->_state->enterState(this);
}
}
#endif