Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion benchmark/Street/BenchStreet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

#include "RoadNetwork.hpp"

using Agent = dsm::Agent<double>;
using Agent = dsm::Agent;
using Street = dsm::Street;
using SparseMatrix = dsm::SparseMatrix<bool>;

Expand Down
2 changes: 1 addition & 1 deletion src/dsm/dsm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

static constexpr uint8_t DSM_VERSION_MAJOR = 2;
static constexpr uint8_t DSM_VERSION_MINOR = 5;
static constexpr uint8_t DSM_VERSION_PATCH = 5;
static constexpr uint8_t DSM_VERSION_PATCH = 6;

static auto const DSM_VERSION =
std::format("{}.{}.{}", DSM_VERSION_MAJOR, DSM_VERSION_MINOR, DSM_VERSION_PATCH);
Expand Down
204 changes: 31 additions & 173 deletions src/dsm/headers/Agent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
#pragma once

#include "Itinerary.hpp"
#include "SparseMatrix.hpp"
#include "../utility/TypeTraits/is_numeric.hpp"
#include "../utility/Logger.hpp"
#include "../utility/Typedef.hpp"

Expand All @@ -25,70 +23,54 @@

namespace dsm {
/// @brief The Agent class represents an agent in the network.
/// @tparam delay_t, The type of the agent's delay. It must be a numeric type (see utility/TypeTraits/is_numeric.hpp).
template <typename delay_t>
requires(is_numeric_v<delay_t>)
class Agent {
private:
Time m_spawnTime, m_freeTime;
Id m_id;
std::vector<Id> m_trip;
std::optional<Id> m_streetId;
std::optional<Id> m_srcNodeId;
std::optional<Id> m_nextStreetId;
delay_t m_delay;
double m_speed;
double m_distance; // Travelled distance
unsigned int m_time; // Travelled time
size_t m_itineraryIdx;
double m_speed;
double m_distance; // Travelled distance

public:
/// @brief Construct a new Agent object
/// @param spawnTime The agent's spawn time
/// @param id The agent's id
/// @param itineraryId Optional, The agent's destination node. If not provided, the agent is a random agent
/// @param srcNodeId Optional, The id of the source node of the agent
Agent(Id id,
Agent(Time const& spawnTime,
Id id,
std::optional<Id> itineraryId = std::nullopt,
std::optional<Id> srcNodeId = std::nullopt);
/// @brief Construct a new Agent object
/// @param spawnTime The agent's spawn time
/// @param id The agent's id
/// @param itineraryIds The agent's itinerary
/// @param srcNodeId Optional, The id of the source node of the agent
Agent(Id id, std::vector<Id> const& trip, std::optional<Id> srcNodeId = std::nullopt);
Agent(Time const& spawnTime,
Id id,
std::vector<Id> const& trip,
std::optional<Id> srcNodeId = std::nullopt);
/// @brief Set the street occupied by the agent
/// @param streetId The id of the street currently occupied by the agent
void setStreetId(Id streetId);
void setStreetId(std::optional<Id> streetId = std::nullopt);

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 17.8 rule Note

MISRA 17.8 rule

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 13.4 rule Note

MISRA 13.4 rule
/// @brief Set the id of the next street
/// @param nextStreetId The id of the next street
void setNextStreetId(Id nextStreetId) { m_nextStreetId = nextStreetId; }
void setNextStreetId(Id nextStreetId);
/// @brief Set the agent's speed
/// @param speed, The agent's speed
/// @throw std::invalid_argument, if speed is negative
void setSpeed(double speed);
/// @brief Increment the agent's delay by 1
/// @throw std::overflow_error, if delay has reached its maximum value
void incrementDelay();
/// @brief Increment the agent's delay by a given value
/// @param delay The agent's delay
/// @throw std::overflow_error, if delay has reached its maximum value
void incrementDelay(delay_t const delay);
/// @brief Decrement the agent's delay by 1
/// @throw std::underflow_error, if delay has reached its minimum value
void decrementDelay();
/// @brief Increment the agent's distance by its speed * 1 second
void incrementDistance() { m_distance += m_speed; }
/// @brief Set the agent's free time
/// @param freeTime The agent's free time
void setFreeTime(Time const& freeTime);
/// @brief Increment the agent's distance by a given value
/// @param distance The value to increment the agent's distance byù
/// @throw std::invalid_argument, if distance is negative
void incrementDistance(double distance);
/// @brief Increment the agent's time by 1
/// @throw std::overflow_error, if time has reached its maximum value
void incrementTime();
/// @brief Increment the agent's time by a given value
/// @param time The value to increment the agent's time by
/// @throw std::overflow_error, if time has reached its maximum value
void incrementTime(unsigned int const time);
/// @brief Reset the agent's time to 0
void resetTime() { m_time = 0; }
/// @brief Update the agent's itinerary
/// @details If possible, the agent's itinerary is updated by removing the first element
/// from the itinerary's vector.
Expand All @@ -101,164 +83,40 @@
/// - distance = 0
/// - time = 0
/// - itinerary index = 0
void reset();
void reset(Time const& spawnTime);

/// @brief Get the agent's spawn time
/// @return The agent's spawn time
Time const& spawnTime() const;
/// @brief Get the agent's free time
/// @return The agent's free time
Time const& freeTime() const;
/// @brief Get the agent's id
/// @return The agent's id
Id id() const { return m_id; }
Id id() const;
/// @brief Get the agent's itinerary
/// @return The agent's itinerary
Id itineraryId() const;
/// @brief Get the agent's trip
/// @return The agent's trip
std::vector<Id> const& trip() const { return m_trip; }
std::vector<Id> const& trip() const;
/// @brief Get the id of the street currently occupied by the agent
/// @return The id of the street currently occupied by the agent
std::optional<Id> streetId() const { return m_streetId; }
std::optional<Id> streetId() const;
/// @brief Get the id of the source node of the agent
/// @return The id of the source node of the agent
std::optional<Id> srcNodeId() const { return m_srcNodeId; }
std::optional<Id> srcNodeId() const;
/// @brief Get the id of the next street
/// @return The id of the next street
std::optional<Id> nextStreetId() const { return m_nextStreetId; }
std::optional<Id> nextStreetId() const;
/// @brief Get the agent's speed
/// @return The agent's speed
double speed() const { return m_speed; }
/// @brief Get the agent's delay
/// @return The agent's delay
delay_t delay() const { return m_delay; }
double speed() const;
/// @brief Get the agent's travelled distance
/// @return The agent's travelled distance
double distance() const { return m_distance; }
/// @brief Get the agent's travel time
/// @return The agent's travel time
unsigned int time() const { return m_time; }
double distance() const;
/// @brief Return true if the agent is a random agent
/// @return True if the agent is a random agent, false otherwise
bool isRandom() const { return m_trip.empty(); }
bool isRandom() const;
};

template <typename delay_t>
requires(is_numeric_v<delay_t>)
Agent<delay_t>::Agent(Id id, std::optional<Id> itineraryId, std::optional<Id> srcNodeId)
: m_id{id},
m_trip{itineraryId.has_value() ? std::vector<Id>{itineraryId.value()}
: std::vector<Id>{}},
m_srcNodeId{srcNodeId},
m_nextStreetId{std::nullopt},
m_delay{0},
m_speed{0.},
m_distance{0.},
m_time{0},
m_itineraryIdx{0} {}

template <typename delay_t>
requires(is_numeric_v<delay_t>)
Agent<delay_t>::Agent(Id id, std::vector<Id> const& trip, std::optional<Id> srcNodeId)
: m_id{id},
m_trip{trip},
m_srcNodeId{srcNodeId},
m_nextStreetId{std::nullopt},
m_delay{0},
m_speed{0.},
m_distance{0.},
m_time{0},
m_itineraryIdx{0} {}

template <typename delay_t>
requires(is_numeric_v<delay_t>)
Id Agent<delay_t>::itineraryId() const {
assert(m_itineraryIdx < m_trip.size());
return m_trip[m_itineraryIdx];
}

template <typename delay_t>
requires(is_numeric_v<delay_t>)
void Agent<delay_t>::setStreetId(Id streetId) {
assert(m_nextStreetId.has_value() ? streetId == m_nextStreetId.value() : true);
m_streetId = streetId;
m_nextStreetId = std::nullopt;
}

template <typename delay_t>
requires(is_numeric_v<delay_t>)
void Agent<delay_t>::setSpeed(double speed) {
if (speed < 0) {
Logger::error(std::format("Speed ({}) of agent {} must be positive", speed, m_id));
}
m_speed = speed;
}
template <typename delay_t>
requires(is_numeric_v<delay_t>)
void Agent<delay_t>::updateItinerary() {
if (m_itineraryIdx < m_trip.size() - 1) {
++m_itineraryIdx;
}
}
template <typename delay_t>
requires(is_numeric_v<delay_t>)
void Agent<delay_t>::reset() {
m_streetId = std::nullopt;
m_delay = 0;
m_speed = 0.;
m_distance = 0.;
m_time = 0;
m_itineraryIdx = 0;
}
template <typename delay_t>
requires(is_numeric_v<delay_t>)
void Agent<delay_t>::incrementDelay() {
if (m_delay == std::numeric_limits<delay_t>::max()) {
throw std::overflow_error(
Logger::buildExceptionMessage("delay_t has reached its maximum value"));
}
++m_delay;
}
template <typename delay_t>
requires(is_numeric_v<delay_t>)
void Agent<delay_t>::incrementDelay(delay_t const delay) {
if (m_delay + delay < m_delay) {
throw std::overflow_error(
Logger::buildExceptionMessage("delay_t has reached its maximum value"));
}
m_delay += delay;
}
template <typename delay_t>
requires(is_numeric_v<delay_t>)
void Agent<delay_t>::decrementDelay() {
if (m_delay == 0) {
throw std::underflow_error(
Logger::buildExceptionMessage("delay_t has reached its minimum value"));
}
--m_delay;
}

template <typename delay_t>
requires(is_numeric_v<delay_t>)
void Agent<delay_t>::incrementDistance(double distance) {
if (distance < 0) {
Logger::error(std::format(
"Distance travelled ({}) by agent {} must be positive", distance, m_id));
}
m_distance += distance;
}

template <typename delay_t>
requires(is_numeric_v<delay_t>)
void Agent<delay_t>::incrementTime() {
if (m_time == std::numeric_limits<unsigned int>::max()) {
throw std::overflow_error(
Logger::buildExceptionMessage("Time has reached its maximum value"));
}
++m_time;
}
template <typename delay_t>
requires(is_numeric_v<delay_t>)
void Agent<delay_t>::incrementTime(unsigned int const time) {
if (m_time + time < m_time) {
throw std::overflow_error(
Logger::buildExceptionMessage("Time has reached its maximum value"));
}
m_time += time;
}
}; // namespace dsm
Loading
Loading