.. _program_listing_file_src_flamegpu_model_SubModelDescription.cpp: Program Listing for File SubModelDescription.cpp ================================================ |exhale_lsh| :ref:`Return to documentation for file ` (``src/flamegpu/model/SubModelDescription.cpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #include "flamegpu/model/SubModelDescription.h" #include "flamegpu/model/ModelData.h" #include "flamegpu/model/AgentData.h" #include "flamegpu/model/SubModelData.h" #include "flamegpu/model/SubAgentData.h" #include "flamegpu/model/SubAgentDescription.h" #include "flamegpu/model/SubEnvironmentData.h" #include "flamegpu/model/SubEnvironmentDescription.h" namespace flamegpu { CSubModelDescription::CSubModelDescription(std::shared_ptr data) : submodel(std::move(data)) { } CSubModelDescription::CSubModelDescription(std::shared_ptr data) : submodel(std::move(std::const_pointer_cast(data))) { } bool CSubModelDescription::operator==(const CSubModelDescription& rhs) const { return *this->submodel == *rhs.submodel; // Compare content is functionally the same } bool CSubModelDescription::operator!=(const CSubModelDescription& rhs) const { return !(*this == rhs); } unsigned int CSubModelDescription::getMaxSteps() const { return submodel->max_steps; } const std::string CSubModelDescription::getName() const { return submodel->name; } SubModelDescription::SubModelDescription(std::shared_ptr data) : CSubModelDescription(std::move(data)) { } SubAgentDescription SubModelDescription::bindAgent(const std::string &sub_agent_name, const std::string &master_agent_name, bool auto_map_vars, bool auto_map_states) { // Sub agent exists const auto subagent = submodel->submodel->agents.find(sub_agent_name); if (subagent == submodel->submodel->agents.end()) { THROW exception::InvalidSubAgentName("SubModel '%s' does not contain Agent '%s', " "in SubModelDescription::bindAgent()\n", submodel->submodel->name.c_str(), sub_agent_name.c_str()); } auto mdl = submodel->model.lock(); if (!mdl) { THROW exception::ExpiredWeakPtr(); } // Master agent exists const auto masteragent = mdl->agents.find(master_agent_name); if (masteragent == mdl->agents.end()) { THROW exception::InvalidAgentName("Master Model '%s' does not contain Agent '%s', " "in SubModelDescription::bindAgent()\n", mdl->name.c_str(), master_agent_name.c_str()); } // Sub agent has not been bound yet { const auto subagent_bind = submodel->subagents.find(sub_agent_name); if (subagent_bind != submodel->subagents.end()) { auto master_agent_ptr = subagent_bind->second->masterAgent.lock(); THROW exception::InvalidSubAgentName("SubModel '%s's Agent '%s' has already been bound to Master agent '%s', " "in SubModelDescription::bindAgent()\n", submodel->submodel->name.c_str(), sub_agent_name.c_str(), master_agent_ptr ? master_agent_ptr->name.c_str() : "?"); } } // Master agent has not been bound yet for (auto &a : submodel->subagents) { const auto master_agent_ptr = a.second->masterAgent.lock(); if (master_agent_ptr && master_agent_ptr->name == master_agent_name) { THROW exception::InvalidAgentName("Master Agent '%s' has already been bound to Sub agent '%s', " "in SubModelDescription::bindAgent()\n", master_agent_name.c_str(), a.first.c_str()); } } // Create SubAgent auto rtn = std::shared_ptr(new SubAgentData(mdl, submodel->shared_from_this(), subagent->second, masteragent->second)); submodel->subagents.emplace(sub_agent_name, rtn); // If auto_map, map any matching vars // Otherwise map all internal variables that begin _ (e.g. _id) for (auto& sub_var : subagent->second->variables) { if (auto_map_vars || (!sub_var.first.empty() && sub_var.first[0] == '_')) { auto master_var = masteragent->second->variables.find(sub_var.first); // If there exists variable with same name in both agents if (master_var != masteragent->second->variables.end()) { // Check type and length (is it an array var) if (sub_var.second.type == master_var->second.type && sub_var.second.elements == master_var->second.elements) { // Variables match, create mapping rtn->variables.emplace(sub_var.first, master_var->first); // Doesn't actually matter, both strings are equal } } } } // If auto_map, map any matching states if (auto_map_states) { for (auto &sub_var : subagent->second->states) { auto master_var = masteragent->second->states.find(sub_var); // If there exists states with same name in both agents if (master_var != masteragent->second->states.end()) { // States match, create mapping rtn->states.emplace(sub_var, *master_var); // Doesn't actually matter, both strings are equal } } } // return SubAgentDescription return SubAgentDescription(rtn); } SubAgentDescription SubModelDescription::SubAgent(const std::string &sub_agent_name) { const auto rtn = submodel->subagents.find(sub_agent_name); if (rtn != submodel->subagents.end()) return SubAgentDescription(rtn->second); THROW exception::InvalidSubAgentName("SubAgent ('%s') either does not exist, or has not been bound yet, " "in SubModelDescription::SubAgent().", sub_agent_name.c_str()); } CSubAgentDescription SubModelDescription::getSubAgent(const std::string &sub_agent_name) const { const auto rtn = submodel->subagents.find(sub_agent_name); if (rtn != submodel->subagents.end()) return SubAgentDescription(rtn->second); THROW exception::InvalidSubAgentName("SubAgent ('%s') either does not exist, or has not been bound yet, " "in SubModelDescription::getSubAgent().", sub_agent_name.c_str()); } SubEnvironmentDescription SubModelDescription::SubEnvironment(bool auto_map) { if (!submodel->subenvironment) { auto mdl = submodel->model.lock(); if (!mdl) { THROW exception::ExpiredWeakPtr(); } submodel->subenvironment = std::shared_ptr(new SubEnvironmentData(mdl, submodel->shared_from_this(), submodel->submodel->environment)); } SubEnvironmentDescription rtn(submodel->subenvironment); if (auto_map) { rtn.autoMapProperties(); rtn.autoMapMacroProperties(); } return rtn; } CSubEnvironmentDescription SubModelDescription::getSubEnvironment() const { if (!submodel->subenvironment) { auto mdl = submodel->model.lock(); if (!mdl) { THROW exception::ExpiredWeakPtr(); } submodel->subenvironment = std::shared_ptr(new SubEnvironmentData(mdl, submodel->shared_from_this(), submodel->submodel->environment)); } return CSubEnvironmentDescription(submodel->subenvironment); } void SubModelDescription::setMaxSteps(const unsigned int max_steps) { submodel->max_steps = max_steps; } } // namespace flamegpu