17 #include "Utilities.h" 23 explicit NodeTypeError(
const char *what) : std::runtime_error(what) {}
24 explicit NodeTypeError(
const std::string &what) : std::runtime_error(what) {}
30 explicit NodeRangeError(
const char *what) : std::out_of_range(what) {}
32 explicit NodeRangeError(
const std::string &what) : std::out_of_range(what) {}
51 using IdPathElement = std::pair<std::string,std::string>;
54 struct IdPath :
public std::vector<IdPathElement> {
56 static constexpr
char PathSep =
'/';
57 static constexpr
char ElementSep =
':';
58 static constexpr std::string_view PathWild =
"*";
59 static constexpr std::string_view PathWildOne =
"?";
60 static constexpr std::string_view PathParent =
"..";
62 explicit IdPath(
bool absolute =
false) : std::vector<IdPathElement>(), absolutePath(absolute) {}
64 explicit IdPath(
const IdPathElement& element,
bool absolute =
false) :
IdPath(absolute) {
65 emplace_back(element);
68 [[nodiscard]] std::string str()
const {
69 bool notFirst =
false;
70 std::stringstream strm{};
71 for (
auto &element : *
this) {
72 if (absolutePath || notFirst) {
75 strm << element.first;
76 if (!element.second.empty())
77 strm << ElementSep << element.second;
83 std::tuple<bool, int> compare(
const IdPath& target) {
84 bool wildCard =
false;
86 auto tgt = target.rbegin();
88 if (tgt == target.rend())
89 return std::make_tuple(
false, 0);
93 if (srch.first == PathWild || srch.first == PathWildOne)
95 while ((srch.first != (*tgt).second) && (srch.first != (*tgt).first)) {
96 if (++tgt == target.rend())
97 return std::make_tuple(
false, 0);
99 if (srch.first == (*tgt).second)
103 if (srch.first == (*tgt).second) {
105 }
else if (srch.first != (*tgt).first) {
106 if (srch.first != PathWildOne) {
107 if (srch.first == PathWild) {
110 return std::make_tuple(
false, 0);
117 return std::make_tuple(
true, score);
122 inline IdPath parsePathIdString(I inputString) {
123 std::stringstream strm;
124 if constexpr (std::is_same_v<std::string_view,I>) {
125 strm.str(std::string{inputString});
127 strm.str(inputString);
131 while (std::getline(strm, tmp, IdPath::PathSep)) {
132 if (idPath.empty() && tmp.empty())
133 idPath.absolutePath =
true;
134 else if (!tmp.empty()) {
135 std::string e1{}, e2{};
136 std::stringstream tstrm{tmp};
137 std::getline(tstrm, e1, IdPath::ElementSep);
138 std::getline(tstrm, e2, IdPath::ElementSep);
139 idPath.emplace_back(e1,e2);
149 std::string_view idString;
151 constexpr
explicit operator bool()
const noexcept {
152 return !idString.empty();
160 class Node :
public std::enable_shared_from_this<Node> {
163 using NodePtr = std::shared_ptr<Node>;
167 std::weak_ptr<Container> mContainer{};
179 explicit Node(
const std::shared_ptr<Container> &container);
181 virtual ~
Node() =
default;
183 static constexpr std::string_view
id =
"Node";
184 virtual std::string_view nodeId()
const noexcept {
209 std::shared_ptr<Container> container() {
210 if (mContainer.expired())
212 return mContainer.lock();
215 std::shared_ptr<Container> container()
const {
216 if (mContainer.expired())
218 return mContainer.lock();
222 std::shared_ptr<C> containerAs() {
223 auto c = container();
225 return std::dynamic_pointer_cast<C>(c);
231 std::shared_ptr<C> containerAs()
const {
232 auto c = container();
234 return std::dynamic_pointer_cast<C>(c);
244 template<
typename NodeType>
245 static std::shared_ptr<NodeType>
create() {
246 return std::make_shared<NodeType>();
256 template<
typename NodeType,
typename ... Args>
257 static std::shared_ptr<NodeType>
create(Args ... args) {
258 return std::make_shared<NodeType>(args ...);
270 template<
typename NodeType,
typename ContainerType,
typename ... Args>
271 static std::shared_ptr<NodeType>
add(ContainerType container, Args ... args) {
272 static_assert(std::is_base_of_v<std::shared_ptr<Container>, ContainerType>,
273 "ContainerType must be derived from Container.");
274 auto node = std::make_shared<NodeType>(args ...);
275 node->mContainer = container;
276 container->add(node);
285 return shared_from_this();
293 return shared_from_this();
302 template<
typename NodeType>
304 return std::dynamic_pointer_cast<NodeType>(shared_from_this());
313 template<
typename NodeType>
315 return std::dynamic_pointer_cast<NodeType>(shared_from_this());
318 std::shared_ptr<Node>
remove();
329 static constexpr std::string_view
id =
"Container";
330 std::string_view nodeId()
const noexcept
override {
334 virtual void add(
const std::shared_ptr<Node> &node) {
335 if (
auto container = getNode<Container>(); container) {
336 container->push_back(node);
338 node->addedToContainer();
342 void remove(
const std::shared_ptr<Node>& node) {
343 erase(std::remove(begin(), end(), node));
347 inline std::shared_ptr<Node> Node::remove() {
348 auto node = shared_from_this();
349 if (
auto container = mContainer.lock(); container) {
350 container->remove(node);
356 auto node = container();
357 auto idPath = node ? node->getIdPath() :
IdPath{
true};
358 idPath.emplace_back(nodeId(),getId());
370 template<
class NodeClass>
371 inline std::shared_ptr<NodeClass> operator<<(std::shared_ptr<NodeClass> widget,
const rose::Id& id) {
372 static_assert(std::is_base_of_v<rose::Node, NodeClass>,
"WidgetClass must be derived from rose::Node.");
378 return ostrm << idPath.str();
std::shared_ptr< NodeClass > operator<<(std::shared_ptr< NodeClass > widget, const rose::Id &id)
An insertion operator to set the Id of a Widget.
Definition: StructuredTypes.h:371
std::shared_ptr< const Node > getNode() const
Get a const std::shared_ptr to this node.
Definition: StructuredTypes.h:284
A container which holds the subordinate Node objects.
Definition: StructuredTypes.h:325
virtual void addedToContainer()
Called when a Node is added to a Container.
Definition: StructuredTypes.h:206
Provide a reverse view of a standard container type.
Definition: Utilities.h:36
std::shared_ptr< Node > getNode()
Get a std::shared_ptr to this node.
Definition: StructuredTypes.h:292
std::shared_ptr< NodeType > getNode()
Get a std::shared_ptr<NodeType> to this node.
Definition: StructuredTypes.h:314
std::string_view getId() const
Get Id.
Definition: StructuredTypes.h:194
IdPath getIdPath() const
Get the Id Path.
Definition: StructuredTypes.h:355
static std::shared_ptr< NodeType > create(Args ... args)
Create a Node with arguments.
Definition: StructuredTypes.h:257
static std::shared_ptr< NodeType > add(ContainerType container, Args ... args)
Create a Node with arguments and add to a Container.
Definition: StructuredTypes.h:271
static std::shared_ptr< NodeType > create()
Create a Node with no arguments.
Definition: StructuredTypes.h:245
std::weak_ptr< Container > mContainer
The Container that holds the Node.
Definition: StructuredTypes.h:167
An exception to indicate an unexpected container type at runtime.
Definition: StructuredTypes.h:41
A class to define a polymorphic member in an N-Array tree.
Definition: StructuredTypes.h:160
A type to specify an Id value.
Definition: StructuredTypes.h:148
Definition: StructuredTypes.h:21
Definition: StructuredTypes.h:28
ToDo: There is an issue that the initial scroll interaction is lost if the click/press lands on a Wid...
Definition: CelestialOverlay.cpp:13
std::shared_ptr< const Node > getNode() const
Get a std::shared_ptr<const NodeType> to this node.
Definition: StructuredTypes.h:303
void setId(const Id &nodeId) noexcept
Set Id.
Definition: StructuredTypes.h:189
A path of objects by Id.
Definition: StructuredTypes.h:54