Program Listing for File ModelDescription.h
↰ Return to documentation for file (include/flamegpu/model/ModelDescription.h
)
#ifndef INCLUDE_FLAMEGPU_MODEL_MODELDESCRIPTION_H_
#define INCLUDE_FLAMEGPU_MODEL_MODELDESCRIPTION_H_
#include <map>
#include <memory>
#include <set>
#include <string>
#include "flamegpu/model/ModelData.h"
#include "flamegpu/runtime/messaging/MessageBruteForce/MessageBruteForceHost.h"
namespace flamegpu {
class AgentDescription;
class CAgentDescription;
class CLayerDescription;
class LayerDescription;
class CSubModelDescription;
class SubModelDescription;
class CEnvironmentDescription;
class EnvironmentDescription;
class DependencyNode;
struct ModelData;
class ModelDescription {
friend class CUDASimulation;
friend class CUDAEnsemble;
friend class RunPlanVector;
friend class RunPlan;
friend class LoggingConfig;
friend class XMLStateReader;
friend class JSONStateReader;
public:
explicit ModelDescription(const std::string &model_name);
ModelDescription(const ModelDescription &other_model) = delete;
ModelDescription(ModelDescription &&other_model) noexcept = delete;
ModelDescription& operator=(const ModelDescription &other_model) = delete;
ModelDescription& operator=(ModelDescription &&other_model) noexcept = delete;
bool operator==(const ModelDescription& rhs) const;
bool operator!=(const ModelDescription& rhs) const;
AgentDescription newAgent(const std::string &agent_name);
AgentDescription Agent(const std::string &agent_name);
template<typename MessageType>
typename MessageType::Description newMessage(const std::string &message_name) {
if (!hasMessage<MessageType>(message_name)) {
auto rtn = std::shared_ptr<typename MessageType::Data>(new typename MessageType::Data(model, message_name));
model->messages.emplace(message_name, rtn);
return typename MessageType::Description(rtn);
}
THROW exception::InvalidMessageName("Message with name '%s' already exists, "
"in ModelDescription::newMessage().",
message_name.c_str());
}
MessageBruteForce::Description newMessage(const std::string &message_name);
template<typename MessageType>
typename MessageType::Description Message(const std::string &message_name) {
auto rtn = model->messages.find(message_name);
if (rtn != model->messages.end()) {
if (auto r = std::dynamic_pointer_cast<typename MessageType::Data>(rtn->second)) {
return typename MessageType::Description(r);
}
THROW exception::InvalidMessageName("Message ('%s') is not of correct type, "
"in ModelDescription::Message().",
message_name.c_str());
}
THROW exception::InvalidMessageName("Message ('%s') was not found, "
"in ModelDescription::Message().",
message_name.c_str());
}
MessageBruteForce::Description Message(const std::string &message_name);
EnvironmentDescription Environment();
SubModelDescription newSubModel(const std::string &submodel_name, const ModelDescription &submodel_description);
SubModelDescription SubModel(const std::string &submodel_name);
LayerDescription newLayer(const std::string &name = "");
LayerDescription Layer(const std::string &name);
LayerDescription Layer(const flamegpu::size_type &layer_index);
void addInitFunction(FLAMEGPU_INIT_FUNCTION_POINTER func_p);
void addStepFunction(FLAMEGPU_STEP_FUNCTION_POINTER func_p);
void addExitFunction(FLAMEGPU_EXIT_FUNCTION_POINTER func_p);
#ifdef SWIG
inline void addInitFunction(HostFunctionCallback *func_callback);
inline void addStepFunction(HostFunctionCallback *func_callback);
inline void addExitFunction(HostFunctionCallback *func_callback);
#endif
void addExitCondition(FLAMEGPU_EXIT_CONDITION_POINTER func_p);
#ifdef SWIG
inline void addExitCondition(HostConditionCallback *func_callback);
#endif
std::string getName() const;
void addExecutionRoot(DependencyNode& root);
void generateLayers();
void generateDependencyGraphDOTDiagram(std::string outputFileName) const;
std::string getConstructedLayersString() const;
CAgentDescription getAgent(const std::string& agent_name) const;
template<typename MessageType>
typename MessageType::CDescription getMessage(const std::string &message_name) const {
auto rtn = model->messages.find(message_name);
if (rtn != model->messages.end()) {
if (auto r = std::dynamic_pointer_cast<typename MessageType::Data>(rtn->second)) {
return typename MessageType::CDescription(r);
}
THROW exception::InvalidMessageType("Message ('%s') is not of correct type, "
"in ModelDescription::getMessage().",
message_name.c_str());
}
THROW exception::InvalidMessageName("Message ('%s') was not found, "
"in ModelDescription::getMessage().",
message_name.c_str());
}
MessageBruteForce::CDescription getMessage(const std::string &message_name) const;
CSubModelDescription getSubModel(const std::string &submodel_name) const;
CEnvironmentDescription getEnvironment() const;
CLayerDescription getLayer(const std::string &name) const;
CLayerDescription getLayer(const flamegpu::size_type &layer_index) const;
bool hasAgent(const std::string &agent_name) const;
template<typename MessageType>
bool hasMessage(const std::string &message_name) const {
auto a = model->messages.find(message_name);
if (a != model->messages.end()) {
if (std::dynamic_pointer_cast<typename MessageType::Data>(a->second))
return true;
}
return false;
}
bool hasMessage(const std::string &message_name) const;
bool hasLayer(const std::string &name) const;
bool hasLayer(const flamegpu::size_type &layer_index) const;
bool hasSubModel(const std::string &submodel_name) const;
flamegpu::size_type getAgentsCount() const;
flamegpu::size_type getMessagesCount() const;
flamegpu::size_type getLayersCount() const;
private:
std::shared_ptr<ModelData> model;
};
#ifdef SWIG
void ModelDescription::addInitFunction(HostFunctionCallback* func_callback) {
if (std::find(model->initFunctionCallbacks.begin(), model->initFunctionCallbacks.end(), func_callback) != model->initFunctionCallbacks.end()) {
THROW exception::InvalidHostFunc("Attempted to add same init function callback twice,"
"in ModelDescription::addInitFunctionCallback()");
}
model->initFunctionCallbacks.push_back(func_callback);
}
void ModelDescription::addStepFunction(HostFunctionCallback* func_callback) {
if (std::find(model->stepFunctionCallbacks.begin(), model->stepFunctionCallbacks.end(), func_callback) != model->stepFunctionCallbacks.end()) {
THROW exception::InvalidHostFunc("Attempted to add same step function callback twice,"
"in ModelDescription::addStepFunctionCallback()");
}
model->stepFunctionCallbacks.push_back(func_callback);
}
void ModelDescription::addExitFunction(HostFunctionCallback* func_callback) {
if (std::find(model->exitFunctionCallbacks.begin(), model->exitFunctionCallbacks.end(), func_callback) != model->exitFunctionCallbacks.end()) {
THROW exception::InvalidHostFunc("Attempted to add same exit function callback twice,"
"in ModelDescription::addExitFunctionCallback()");
}
model->exitFunctionCallbacks.push_back(func_callback);
}
void ModelDescription::addExitCondition(HostConditionCallback *func_callback) {
if (std::find(model->exitConditionCallbacks.begin(), model->exitConditionCallbacks.end(), func_callback) != model->exitConditionCallbacks.end()) {
THROW exception::InvalidHostFunc("Attempted to add same exit condition callback twice,"
"in ModelDescription::addExitConditionCallback()");
}
model->exitConditionCallbacks.push_back(func_callback);
}
#endif
} // namespace flamegpu
#endif // INCLUDE_FLAMEGPU_MODEL_MODELDESCRIPTION_H_