Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 1 addition & 36 deletions devOpcuaSup/DataElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@
#define DEVOPCUA_DATAELEMENT_H

#include <map>
#include <vector>
#include <memory>
#include <cstring>

#include <epicsTypes.h>
#include <epicsTime.h>
Expand Down Expand Up @@ -63,13 +60,6 @@ class DataElement
RecordConnector *pconnector,
const std::list<std::string> &elementPath);

/**
* @brief Get the type of element (inside a structure).
*
* @return true if element is a leaf (has no child elements)
*/
bool isLeaf() const { return isleaf; }

/**
* @brief Setter to create a (bidirectional) link to a RecordConnector.
*
Expand Down Expand Up @@ -799,35 +789,10 @@ class DataElement
*/
virtual void requestRecordProcessing(const ProcessReason reason) const = 0;

const std::string name; /**< element name */
const EnumChoices* enumChoices = nullptr; /**< enum definition if this element is an enum */

protected:
/**
* @brief Constructor for node DataElement, to be used by implementations.
*
* @param name structure element name (empty otherwise)
*/
DataElement(const std::string &name = "")
: name(name)
, pconnector(nullptr)
, isleaf(false)
{}

/**
* @brief Constructor for leaf DataElement, to be used by implementations.
*
* @param name structure element name (empty otherwise)
* @param connector
*/
DataElement(RecordConnector *pconnector, const std::string &name = "")
: name(name)
, pconnector(pconnector)
, isleaf(true)
{}

RecordConnector *pconnector; /**< pointer to connector (if leaf) */
const bool isleaf; /**< flag for leaf property */
RecordConnector *pconnector = nullptr;
};

} // namespace DevOpcua
Expand Down
57 changes: 24 additions & 33 deletions devOpcuaSup/ElementTree.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*************************************************************************\
* Copyright (c) 2020-2021 ITER Organization.
* Copyright (c) 2020-2025 ITER Organization.
* This module is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
Expand Down Expand Up @@ -41,35 +41,28 @@ namespace DevOpcua {
* The template types used (all specific to the implementation) and their
* constraints:
*
* E is the Element class
* with a constructor E::E(const std::string &name, I *item)
* and methods void E::setParent(std::shared_ptr<E> parent);
* void E::addChild(std::weak_ptr<E> child);
* std::shared_ptr<E> findChild(const std::string &name)
* bool E::isLeaf();
* and a public const std::string E::name;
* NE is the Node Element class
* with a constructor NE::NE(const std::string &name, I *item)
* and methods void NE::setParent(std::shared_ptr<NE> parent);
* void NE::addChild(std::weak_ptr<NE> child);
* std::shared_ptr<NE> findChild(const std::string &name)
*
* I is the Item class.
* E is the common base class of Node Element (NE) and Leaf Element
* with the method void E::setParent(std::shared_ptr<E> parent);
*
* I is the Item class
*/

template<typename E, typename I>
template<typename NE, typename E, typename I>
class ElementTree
{
public:
ElementTree(I *i)
: item(i)
{}

/**
* @brief Return root element
*
* @return weak_ptr to root element
*/
std::weak_ptr<E>
root() const
{
return rootElement;
}
std::weak_ptr<E> root() const { return rootElement; }

/* Allow testing as 'if (tree) ...' */
explicit operator bool() const { return !rootElement.expired(); }
Expand All @@ -82,8 +75,7 @@ class ElementTree
*
* @return shared_ptr to the nearest existing node in the tree, shared_ptr<>() if no overlap
*/
std::shared_ptr<E>
nearestNode(std::list<std::string> &path)
std::shared_ptr<E> nearestNode(std::list<std::string> &path)
{
bool found;

Expand All @@ -97,7 +89,7 @@ class ElementTree
do {
auto part = path.begin();
found = false;
if (elem) {
if (elem && !elem->isLeaf()) {
auto nextelem = elem->findChild(*part);
if (nextelem) {
found = true;
Expand All @@ -107,10 +99,7 @@ class ElementTree
}
} while (found && !path.empty());

if (elem)
return elem;
else
return std::shared_ptr<E>();
return elem;
}

/**
Expand All @@ -120,25 +109,25 @@ class ElementTree
* @param path full path of the leaf
*
* @throws runtime_error when trying to add elements to a leaf node
* when adding with empty path but [ROOT] exists
*/
void
addLeaf(std::shared_ptr<E> leaf, const std::list<std::string> &fullpath)
void addLeaf (std::shared_ptr<E> leaf, const std::list<std::string> &fullpath, I *item)
{
std::shared_ptr<E> elem(leaf);
std::list<std::string> path(fullpath);

auto branch = nearestNode(path);

if (branch && branch->isLeaf())
throw std::runtime_error(SB()
<< "can't add leaf to existing leaf " << branch->name);
throw std::runtime_error(SB() << "can't add leaf to existing leaf " << branch->name);
if (path.empty()) {
if (rootElement.lock())
throw std::runtime_error(SB() << "root node does already exist");
rootElement = elem;
} else {
path.pop_back(); // remove the leaf name
for (auto rit = path.crbegin(); rit != path.crend(); ++rit) {
auto node = std::make_shared<E>(*rit, item);
auto node = std::make_shared<NE>(*rit, item);
node->addChild(elem);
elem->setParent(node);
elem = std::move(node);
Expand All @@ -147,17 +136,19 @@ class ElementTree
branch->addChild(elem);
elem->setParent(branch);
} else {
auto node = std::make_shared<E>("[ROOT]", item);
auto node = std::make_shared<NE>("[ROOT]", item);
node->addChild(elem);
elem->setParent(node);
rootElement = std::move(node);
}
}
}

public:
void setRoot(std::shared_ptr<E> root) { rootElement = root; }

private:
std::weak_ptr<E> rootElement;
I *item;
};

} // namespace DevOpcua
Expand Down
Loading
Loading