.. _program_listing_file_include_flamegpu_model_AgentDescription.h: Program Listing for File AgentDescription.h =========================================== |exhale_lsh| :ref:`Return to documentation for file ` (``include/flamegpu/model/AgentDescription.h``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #ifndef INCLUDE_FLAMEGPU_MODEL_AGENTDESCRIPTION_H_ #define INCLUDE_FLAMEGPU_MODEL_AGENTDESCRIPTION_H_ #include #include #include #include #include #include #include "flamegpu/model/Variable.h" #include "flamegpu/model/ModelDescription.h" #include "flamegpu/simulation/AgentVector.h" #include "flamegpu/runtime/agent/AgentInstance.h" #include "flamegpu/model/AgentData.h" #include "flamegpu/detail/type_decode.h" namespace flamegpu { class CAgentFunctionDescription; class AgentFunctionDescription; class AgentDescription; namespace visualiser { struct AgentVisData; } class CAgentDescription { friend struct AgentData; friend AgentVector::AgentVector(const CAgentDescription& agent_desc, flamegpu::size_type); friend AgentInstance::AgentInstance(const CAgentDescription& agent_desc); friend bool AgentVector::matchesAgentType(const CAgentDescription& other) const; friend struct visualiser::AgentVisData; public: explicit CAgentDescription(std::shared_ptr data); explicit CAgentDescription(std::shared_ptr data); CAgentDescription(const CAgentDescription& other_agent) = default; CAgentDescription(CAgentDescription&& other_agent) = default; CAgentDescription& operator=(const CAgentDescription& other_agent) = default; CAgentDescription& operator=(CAgentDescription&& other_agent) = default; bool operator==(const CAgentDescription& rhs) const; bool operator!=(const CAgentDescription& rhs) const; std::string getName() const; flamegpu::size_type getStatesCount() const; std::string getInitialState() const; const std::type_index& getVariableType(const std::string& variable_name) const; size_t getVariableSize(const std::string& variable_name) const; flamegpu::size_type getVariableLength(const std::string& variable_name) const; flamegpu::size_type getVariablesCount() const; CAgentFunctionDescription getFunction(const std::string& function_name) const; flamegpu::size_type getFunctionsCount() const; flamegpu::size_type getAgentOutputsCount() const; bool hasState(const std::string& state_name) const; bool hasVariable(const std::string& variable_name) const; bool hasFunction(const std::string& function_name) const; bool isOutputOnDevice() const; const std::set& getStates() const; protected: std::shared_ptr agent; }; class AgentDescription : public CAgentDescription { friend struct AgentFunctionData; friend class DependencyGraph; friend class AgentFunctionDescription; public: explicit AgentDescription(std::shared_ptr data); AgentDescription(const AgentDescription& other_agent) = default; AgentDescription(AgentDescription&& other_agent) = default; AgentDescription& operator=(const AgentDescription& other_agent) = default; AgentDescription& operator=(AgentDescription&& other_agent) = default; void newState(const std::string &state_name); void setInitialState(const std::string &initial_state); template void newVariable(const std::string &variable_name, const std::array &default_value = {}); #ifndef SWIG template void newVariable(const std::string& variable_name, T default_value = {}); #else template void newVariable(const std::string& variable_name, T default_value = 0); template void newVariableArray(const std::string &variable_name, const flamegpu::size_type &length, const std::vector&default_value = {}); #endif template AgentFunctionDescription newFunction(const std::string &function_name, AgentFunction a = AgentFunction()); AgentFunctionDescription newRTCFunction(const std::string& function_name, const std::string& func_src); AgentFunctionDescription newRTCFunctionFile(const std::string& function_name, const std::string& file_path); AgentFunctionDescription Function(const std::string &function_name); void setSortPeriod(const unsigned int sortPeriod); }; template void AgentDescription::newVariable(const std::string &variable_name, const std::array &default_value) { if (!variable_name.empty() && variable_name[0] == '_') { THROW exception::ReservedName("Agent variable names cannot begin with '_', this is reserved for internal usage, " "in AgentDescription::newVariable()."); } std::string lower_variable_name = variable_name; for (auto& c : lower_variable_name) c = static_cast(tolower(c)); if (lower_variable_name == "name" || lower_variable_name == "state") { THROW exception::ReservedName("Agent variables cannot be named 'name' or 'state', these are reserved for backwards compatibility reasons, " "in AgentDescription::newVariable()."); } if (lower_variable_name == "_auto_sort_bin_index") { THROW exception::ReservedName("The variable name '_auto_sort_bin_index' is reserved for internal usage, " "in AgentDescription::newVariable()."); } // Array length 0 makes no sense static_assert(detail::type_decode::len_t * N > 0, "A variable cannot have 0 elements."); if (agent->variables.find(variable_name) == agent->variables.end()) { const std::array::type_t, detail::type_decode::len_t * N> *casted_default = reinterpret_cast::type_t, detail::type_decode::len_t* N>*>(&default_value); agent->variables.emplace(variable_name, Variable(*casted_default)); return; } THROW exception::InvalidAgentVar("Agent ('%s') already contains variable '%s', " "in AgentDescription::newVariable().", agent->name.c_str(), variable_name.c_str()); } template void AgentDescription::newVariable(const std::string &variable_name, const T default_value) { newVariable(variable_name, { default_value }); } #ifdef SWIG template void AgentDescription::newVariableArray(const std::string& variable_name, const flamegpu::size_type& length, const std::vector& default_value) { if (!variable_name.empty() && variable_name[0] == '_') { THROW exception::ReservedName("Agent variable names cannot begin with '_', this is reserved for internal usage, " "in AgentDescription::newVariable()."); } std::string lower_variable_name = variable_name; for (auto& c : lower_variable_name) c = static_cast(tolower(c)); if (lower_variable_name == "name" || lower_variable_name == "state") { THROW exception::ReservedName("Agent variables cannot be named 'name' or 'state', these are reserved for backwards compatibility reasons, " "in AgentDescription::newVariable()."); } if (length == 0) { THROW exception::InvalidAgentVar("Agent variable arrays must have a length greater than 0." "in AgentDescription::newVariable()."); } if (default_value.size() && default_value.size() != length) { THROW exception::InvalidAgentVar("Agent variable array length specified as %d, but default value provided with %llu elements, " "in AgentDescription::newVariable().", length, static_cast(default_value.size())); } if (agent->variables.find(variable_name) == agent->variables.end()) { std::vector::type_t> temp(static_cast(detail::type_decode::len_t * length)); if (default_value.size()) { memcpy(temp.data(), default_value.data(), sizeof(typename detail::type_decode::type_t) * detail::type_decode::len_t * length); } agent->variables.emplace(variable_name, Variable(detail::type_decode::len_t* length, temp)); return; } THROW exception::InvalidAgentVar("Agent ('%s') already contains variable '%s', " "in AgentDescription::newVariable().", agent->name.c_str(), variable_name.c_str()); } #endif // Found in "flamegpu/model/AgentFunctionDescription.h" // template // AgentFunctionDescription &AgentDescription::newFunction(const std::string &function_name, AgentFunction) } // namespace flamegpu #endif // INCLUDE_FLAMEGPU_MODEL_AGENTDESCRIPTION_H_