9#include "sparta/log/MessageSource.hpp"
13#include "sparta/simulation/ResourceFactory.hpp"
14#include "sparta/functional/ArchData.hpp"
47 template <
typename ResourceT,
typename ParamsT>
77 const std::string & name,
78 const std::string & group,
80 const std::string & desc,
81 const ParamsT* params) :
82 TreeNode(name, group, group_idx, desc),
88 if(
nullptr == parent){
89 throw SpartaException(
"Cannot create a DynamicResourceTreeNode without a non-null parent. Error at: ")
96 <<
getName() <<
"\"@" << (
void*)
this <<
" because it is not attached to a tree with a RootTreeNode";
99 if(
nullptr == params){
106 <<
getLocation() <<
" and no ancestor has an associated clock. A DynamicResourceTreeNode "
107 <<
"must have at least one clock associated with a node in their ancestry";
112 if(parent !=
nullptr){
119 const std::string & name,
120 const std::string & desc,
121 const ParamsT* params) :
140 throw SpartaException(
"Cannot re-finalize this DynamicResourceTreeNode: ")
141 <<
getLocation() <<
" because it already has a resource";
154 virtual std::string
stringize(
bool pretty=
false)
const override {
156 std::stringstream ss;
157 ss <<
"<" <<
getLocation() <<
" dynamic resource: \"" <<
demangle(
typeid(ResourceT).name()) <<
"\">";
186 virtual void createResource_()
override {
196 throw SpartaException(
"Tried to create resource through DynamicResourceTreeNode ")
197 <<
getLocation() <<
" but tree was not in TREE_FINALIZING phase";
201 throw SpartaException(
"No clock associated with DynamicResourceTreeNode ")
202 <<
getLocation() <<
" and no ancestor has an associated clock. All DynamicResourceTreeNodes "
203 <<
"must have at least one clock associated with a node in their ancestry";
207 if(!params_->validateIndependently(errs)){
208 throw SpartaException(
"Parameter limits violated:")
212 if(!params_->validateDependencies(
this, errs)){
213 throw SpartaException(
"Parameter validation callbacks indicated invalid parameters: ")
217 res_.reset(
new ResourceT(
this, params_));
220 throw SpartaException(
"DynamicResourceTreeNode ") <<
getLocation()
221 <<
" created a resource of type " <<
demangle(
typeid(ResourceT).name())
222 <<
" but that resource did not register itself with this node. Ensure that "
223 "this resource class uses the proper sparta::Resource base-class constructor "
224 "which takes a ResourceContainer";
227 throw SpartaException(
"DynamicResourceTreeNode ") <<
getLocation()
228 <<
" created a resource of type " <<
demangle(
typeid(ResourceT).name())
229 <<
" but that resource was different than the resource registered with this "
236 virtual void onSettingParent_(
const TreeNode* parent)
const override {
239 throw SpartaException(
"Cannot add DynamicResourceTreeNode \"")
240 <<
getName() <<
"\" as child of device tree node \""
241 <<
getLocation() <<
"\". This tree has exited the TREE_BUILDING "
242 <<
"phase and ResourceTreeNodes can no longer be added.";
246 std::unique_ptr<ResourceT> res_;
260 const ParamsT* params_;
A set of sparta::Parameters per sparta::ResourceTreeNode.
Set of macros for Sparta assertions. Caught by the framework.
#define sparta_assert(...)
Simple variadic assertion that will throw a sparta_exception if the condition fails.
Exception class for all of Sparta.
Basic Node framework in sparta device tree composite pattern.
void layout()
Organizes the Segments into overlapping regions as needed, eventually calling ArchDataSegment::place ...
TreeNode subclass representing a node in the device tree which creates and owns a resource....
DynamicResourceTreeNode(TreeNode *parent, const std::string &name, const std::string &desc, const ParamsT *params)
Alternate constructor.
virtual ~DynamicResourceTreeNode()
Virtual Destructor.
static const ArchData::offset_type ARCH_DATA_LINE_SIZE
Size of an ArchData line for ResourceTreeNode (bytes) ArchData for ResourceTreeNode is a catch-all sp...
void finalize()
Finalize this node and construct its resource.
DynamicResourceTreeNode(TreeNode *parent, const std::string &name, const std::string &group, group_idx_type group_idx, const std::string &desc, const ParamsT *params)
Dynamic, Non-factory constructor. Useful when no predefined factory object is necessary....
virtual std::string stringize(bool pretty=false) const override
Render description of this ResourceTreeNode as a string.
virtual bool isBuilt() const
Is this node (and thus the entire tree above it) "built". Checks that getPhase has passed TREE_BUILDI...
TreePhase getPhase() const
Gets the trees current phase.
@ TREE_FINALIZING
Tree is being finalized, but has not completed (maybe errors?)
void lockResource_()
Allows subclasses to assign the resource associated with this node.
Resource * getResource_() noexcept
Returns the currently held resource of this node (if any). This method can be called at any time.
Used to construct and throw a standard C++ exception. Inherits from std::exception.
Node in a composite tree representing a sparta Tree item.
static const group_idx_type GROUP_IDX_NONE
GroupIndex indicating that a node has no group index because it belongs to no group.
std::string getLocation() const override final
static constexpr char GROUP_NAME_NONE[]
Group name indicating that a node belongs to no group.
virtual bool isAttached() const
Is this node part of a device tree with a proper RootTreeNode at the root.
TreeNode()=delete
Not default-constructable.
void addChild(TreeNode *child, bool inherit_phase=true)
Adds a TreeNode to this node as a child.
virtual TreeNode * getParent()
Gets immediate parent of this node if one exists.
uint32_t group_idx_type
Index within a group.
const Clock * getClock() override
Walks up parents (starting with self) until a parent with an associated local clock is found,...
const std::string & getName() const override
Gets the name of this node.
void setExpectedParent_(const TreeNode *parent)
Tracks a node as an expected parent without actually adding this node as a child. This is used almost...
Macros for handling exponential backoff.
std::string demangle(const std::string &name) noexcept
Demangles a C++ symbol.