Skip to content

Commit

Permalink
support field disconnection for linking components
Browse files Browse the repository at this point in the history
  • Loading branch information
ydaveluy committed Jul 20, 2024
1 parent 28f028f commit ba61ee8
Show file tree
Hide file tree
Showing 26 changed files with 388 additions and 216 deletions.
4 changes: 2 additions & 2 deletions include/Xsmp/Array.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ template <typename Tp> struct _array_traits<Tp, 0> {
// Empty type used instead of Tp[0] for Xsmp::Array<Tp, 0>.
struct type {
// Indexing is undefined.
Tp &operator[](std::size_t) const noexcept { std::abort(); }
Tp &operator[](size_t) const noexcept { std::abort(); }

// Conversion to a pointer produces a null pointer.
constexpr explicit operator Tp *() const noexcept { return nullptr; }
Expand All @@ -68,7 +68,7 @@ template <typename Tp, std::size_t Nm, typename... options> struct Array {
using const_reference = const value_type &;
using iterator = value_type *;
using const_iterator = const value_type *;
using size_type = std::size_t;
using size_type = size_t;
using difference_type = std::ptrdiff_t;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
Expand Down
24 changes: 7 additions & 17 deletions include/Xsmp/Collection.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#include <Xsmp/Exception.h>
#include <Xsmp/Object.h>
#include <algorithm>
#include <stddef.h>
#include <cstddef>
#include <string_view>
#include <unordered_map>
#include <vector>
Expand Down Expand Up @@ -64,15 +64,11 @@ template <typename T> class AbstractCollection : public ::Smp::ICollection<T> {

/// Get the begin iterator
/// @return Begin iterator
const_iterator begin() const override {
return AbstractCollection<T>::const_iterator(*this, 0);
}
const_iterator begin() const override { return {*this, 0}; }

/// Get the end iterator
/// @return End iterator
const_iterator end() const override {
return AbstractCollection<T>::const_iterator(*this, _vector.size());
}
const_iterator end() const override { return {*this, _vector.size()}; }

/// Add an element to the collection
/// @param element The element to add to the collection.
Expand Down Expand Up @@ -172,13 +168,11 @@ class ContainingCollection final : public ::Xsmp::Object,

/// Get the begin iterator
/// @return Begin iterator
const_iterator begin() const override { return const_iterator(*this, 0); }
const_iterator begin() const override { return {*this, 0}; }

/// Get the end iterator
/// @return End iterator
const_iterator end() const override {
return const_iterator(*this, _vector.size());
}
const_iterator end() const override { return {*this, _vector.size()}; }

/// Add an element to the collection
/// @tparam U The type of the element to add
Expand Down Expand Up @@ -291,15 +285,11 @@ class DelegateCollection final : public ::Xsmp::detail::AbstractCollection<T> {

/// Get the begin iterator
/// @return Begin iterator
const_iterator begin() const override {
return DelegateCollection<T>::const_iterator(*this, 0);
}
const_iterator begin() const override { return {*this, 0}; }

/// Get the end iterator
/// @return End iterator
const_iterator end() const override {
return DelegateCollection<T>::const_iterator(*this, size());
}
const_iterator end() const override { return {*this, size()}; }

::Smp::String8 GetName() const override { return _delegate->GetName(); }
::Smp::String8 GetDescription() const override {
Expand Down
2 changes: 2 additions & 0 deletions include/Xsmp/Component.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,8 @@ class Component : public virtual ::Smp::ILinkingComponent,
const ::Smp::IComponent *target) noexcept;
static void RemoveAggregateLinks(const ::Smp::IAggregate *aggregate,
const ::Smp::IComponent *target) noexcept;
static void RemoveFieldLinks(::Smp::IField *field,
const ::Smp::IComponent *target) noexcept;

::Xsmp::cstring _name;
::Xsmp::cstring _description;
Expand Down
2 changes: 1 addition & 1 deletion include/Xsmp/Container.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#include <Xsmp/Exception.h>
#include <Xsmp/cstring.h>
#include <algorithm>
#include <stddef.h>
#include <cstddef>
#include <stdexcept>
#include <string_view>
#include <vector>
Expand Down
10 changes: 6 additions & 4 deletions include/Xsmp/DateTime.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,13 @@ namespace Xsmp {

/**
* @class DateTime
* @brief This class represents a point in time that can be manipulated and compared.
* @brief This class represents a point in time that can be manipulated and
* compared.
*
* The DateTime class provides functionality to manage time-related operations. It allows you to initialize
* date and time objects, format them into strings, convert between different time representations,
* perform arithmetic operations on dates and times, and output the formatted date and time values to streams.
* The DateTime class provides functionality to manage time-related operations.
* It allows you to initialize date and time objects, format them into strings,
* convert between different time representations, perform arithmetic operations
* on dates and times, and output the formatted date and time values to streams.
*/
struct DateTime final {

Expand Down
80 changes: 57 additions & 23 deletions include/Xsmp/Field.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
#include <Xsmp/cstring.h>
#include <cstddef>
#include <iterator>
#include <set>
#include <type_traits>
#include <utility>

Expand Down Expand Up @@ -179,20 +178,47 @@ class IDataflowFieldExtension : public virtual ::Smp::IDataflowField {
public:
/// Virtual destructor to release memory.
~IDataflowFieldExtension() noexcept override = default;

/// Disconnect this field to a target field for direct data flow.
/// @param target Target field to connect to. The field type must be
/// compatible.
virtual void Disconnect(::Smp::IField *target) = 0;
virtual void Disconnect(const ::Smp::IField *target) = 0;

virtual const ::Smp::FieldCollection *GetInputFields() const {
return nullptr;
};
};

class InputFieldCollection final : public ::Xsmp::Object,
public ::Smp::FieldCollection {
public:
using ::Xsmp::Object::Object;
using const_iterator = typename ::Smp::FieldCollection::const_iterator;
using iterator = typename ::Smp::FieldCollection::iterator;
::Smp::IField *at(::Smp::String8 name) const override;
::Smp::IField *at(size_t index) const override;
size_t size() const override;
virtual bool empty() const;
const_iterator begin() const override;
const_iterator end() const override;
bool contains(const ::Smp::IField *input) const;
void add(::Smp::IField *input);
bool remove(const ::Smp::IField *input);

private:
std::vector<::Smp::IField *> _fields;
};
class ArrayDataflowField : public virtual IDataflowFieldExtension,
public virtual ::Smp::IArrayField {
public:
ArrayDataflowField();
void Push() final;
void Connect(::Smp::IField *target) final;
void Disconnect(::Smp::IField *target) final;
void Disconnect(const ::Smp::IField *target) final;
const ::Smp::FieldCollection *GetInputFields() const final;

private:
std::set<::Smp::IArrayField *> _connectedFields;
InputFieldCollection _connectedFields;
friend class ::Xsmp::detail::FieldHelper;
};

Expand All @@ -203,18 +229,21 @@ using ArrayField = std::conditional_t<

class SimpleConnectableField : public virtual ::Smp::ISimpleField {
protected:
SimpleConnectableField();
void internal_push() const;
const ::Smp::FieldCollection *GetInputFields() const;

private:
std::set<::Smp::ISimpleField *> _connectedFields;
InputFieldCollection _connectedFields;
friend class ::Xsmp::detail::FieldHelper;
};
class SimpleDataflowField : public virtual SimpleConnectableField,
public virtual IDataflowFieldExtension {
public:
void Push() final;
void Connect(::Smp::IField *target) final;
void Disconnect(::Smp::IField *target) final;
void Disconnect(const ::Smp::IField *target) final;
const ::Smp::FieldCollection *GetInputFields() const final;
};
template <typename... Annotations>
using SimpleField = std::conditional_t<
Expand All @@ -226,10 +255,12 @@ using SimpleField = std::conditional_t<

class SimpleArrayConnectableField : public virtual ::Smp::ISimpleArrayField {
protected:
SimpleArrayConnectableField();
void internal_push(::Smp::UInt64 index) const;
const ::Smp::FieldCollection *GetInputFields() const;

private:
std::set<::Smp::ISimpleArrayField *> _connectedFields;
InputFieldCollection _connectedFields;
friend class ::Xsmp::detail::FieldHelper;
};

Expand All @@ -238,7 +269,8 @@ class SimpleArrayDataflowField : public virtual SimpleArrayConnectableField,
public:
void Push() final;
void Connect(::Smp::IField *target) final;
void Disconnect(::Smp::IField *target) final;
void Disconnect(const ::Smp::IField *target) final;
const ::Smp::FieldCollection *GetInputFields() const final;
};
template <typename... Annotations>
using SimpleArrayField = std::conditional_t<
Expand Down Expand Up @@ -291,12 +323,14 @@ class AbstractStructureField : public virtual ::Smp::IStructureField {
class StructureDataflowField : public ::Xsmp::detail::AbstractStructureField,
public virtual IDataflowFieldExtension {
public:
StructureDataflowField();
void Push() final;
void Connect(::Smp::IField *target) final;
void Disconnect(::Smp::IField *target) final;
void Disconnect(const ::Smp::IField *target) final;
const ::Smp::FieldCollection *GetInputFields() const final;

private:
std::set<::Smp::IStructureField *> _connectedFields;
InputFieldCollection _connectedFields;
friend class ::Xsmp::detail::FieldHelper;
};
template <typename... Annotations>
Expand Down Expand Up @@ -503,7 +537,7 @@ class ArrayField final
: public ::Xsmp::detail::Field<T, Annotations...>,
public virtual ::Xsmp::detail::ArrayField<Annotations...> {

static constexpr std::size_t _size = ::Xsmp::detail::FieldTypeHelper<T>::size;
static constexpr size_t _size = ::Xsmp::detail::FieldTypeHelper<T>::size;

template <typename... Options> struct apply_options {
template <typename U> struct on {
Expand Down Expand Up @@ -596,7 +630,7 @@ class ArrayField final
using const_reference = const value_type &;
using iterator = value_type *;
using const_iterator = const value_type *;
using size_type = std::size_t;
using size_type = size_t;
using difference_type = std::ptrdiff_t;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
Expand Down Expand Up @@ -687,7 +721,7 @@ class ArrayField final
}

private:
template <std::size_t... I>
template <size_t... I>
::Xsmp::Array<value_type, _size>
create_array_impl(::Smp::Publication::ITypeRegistry *typeRegistry,
const T &value, std::index_sequence<I...>) {
Expand All @@ -711,7 +745,7 @@ class SimpleArrayField final
static_assert(
!::Xsmp::Annotation::any_of<::Xsmp::Annotation::forcible, Annotations...>,
"A SimpleArrayField cannot be forcible.");
static constexpr std::size_t _size = ::Xsmp::detail::FieldTypeHelper<T>::size;
static constexpr size_t _size = ::Xsmp::detail::FieldTypeHelper<T>::size;

public:
SimpleArrayField(const SimpleArrayField &) = delete;
Expand Down Expand Up @@ -753,7 +787,7 @@ class SimpleArrayField final
::Xsmp::Exception::throwInvalidArraySize(this, length);
}
auto _itemKind = _type->GetItemType()->GetPrimitiveTypeKind();
for (std::size_t i = 0; i < _size; ++i) {
for (size_t i = 0; i < _size; ++i) {
values[i] =
::Xsmp::AnySimpleConverter<value_type>::convert(_itemKind, _value[i]);
}
Expand All @@ -764,7 +798,7 @@ class SimpleArrayField final
::Xsmp::Exception::throwInvalidArraySize(this, length);
}
auto _itemKind = _type->GetItemType()->GetPrimitiveTypeKind();
for (std::size_t i = 0; i < _size; ++i) {
for (size_t i = 0; i < _size; ++i) {
if (values[i].type != _itemKind) {
::Xsmp::Exception::throwInvalidArrayValue(this, i, values[i]);
}
Expand Down Expand Up @@ -796,7 +830,7 @@ class SimpleArrayField final

struct protected_reference {
protected_reference(SimpleArrayField *parent, value_type &value,
std::size_t index)
size_t index)
: _parent{parent}, _value{value}, _index{index} {}

operator const T &() const noexcept { return _value; }
Expand Down Expand Up @@ -860,15 +894,15 @@ class SimpleArrayField final
}
SimpleArrayField *_parent;
value_type &_value;
std::size_t _index;
size_t _index;
};

using reference =
std::conditional_t<::Xsmp::Annotation::any_of<
::Xsmp::Annotation::connectable, Annotations...>,
protected_reference, value_type &>;
using const_reference = const value_type &;
using size_type = std::size_t;
using size_type = size_t;
using difference_type = std::ptrdiff_t;
struct protected_iterator {
using iterator_category = std::forward_iterator_tag;
Expand All @@ -878,7 +912,7 @@ class SimpleArrayField final
using reference = SimpleArrayField::reference;

protected_iterator(SimpleArrayField *parent, value_type *value,
std::size_t index)
size_t index)
: _parent{parent}, _value{value}, _index{index} {}
friend inline bool operator==(const protected_iterator &lhs,
const protected_iterator &rhs) {
Expand Down Expand Up @@ -940,7 +974,7 @@ class SimpleArrayField final
private:
SimpleArrayField *_parent;
value_type *_value;
std::size_t _index;
size_t _index;
};

using iterator =
Expand Down Expand Up @@ -1191,7 +1225,7 @@ struct FieldTypeHelper<::Xsmp::Array<T, Nm, TypeAnnotations...>,
template <typename... Annotations>
using field = ::Xsmp::ArrayField<::Xsmp::Array<T, Nm, TypeAnnotations...>,
Annotations...>;
static constexpr std::size_t size = Nm;
static constexpr size_t size = Nm;
};

template <typename T, std::size_t Nm, typename... TypeAnnotations>
Expand All @@ -1203,7 +1237,7 @@ struct FieldTypeHelper<::Xsmp::Array<T, Nm, TypeAnnotations...>,
using field =
::Xsmp::SimpleArrayField<::Xsmp::Array<T, Nm, TypeAnnotations...>,
Annotations...>;
static constexpr std::size_t size = Nm;
static constexpr size_t size = Nm;
};

} // namespace detail
Expand Down
9 changes: 9 additions & 0 deletions include/Xsmp/Helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,15 @@ template <typename T>
return nullptr;
}

/// Returns whether the second object is the same as the first object, or is
/// directly contained by the first object, i.e., whether the second object is
/// in the content tree of the first.
/// @param ancestorObject The ancestor object in question.
/// @param object The object to test.
/// @return Whether the first object is an ancestor of the second object..
[[nodiscard]] bool IsAncestor(const ::Smp::IObject *ancestorObject,
const ::Smp::IObject *object);

/// Compares two SMP fields to determine if they are equivalent based on their
/// types.
/// @param first The first IField object to be compared for equivalence.
Expand Down
6 changes: 3 additions & 3 deletions include/Xsmp/Persist.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,13 @@ void Restore(const ::Smp::ISimulator *simulator, ::Smp::IStorageReader *reader,
template <typename T, std::size_t N> struct Helper<T[N]> {
static void Store(const ::Smp::ISimulator *simulator,
::Smp::IStorageWriter *writer, const T (&value)[N]) {
for (std::size_t i = 0; i < N; ++i) {
for (size_t i = 0; i < N; ++i) {
::Xsmp::Persist::Store(simulator, writer, value[i]);
}
}
static void Restore(const ::Smp::ISimulator *simulator,
::Smp::IStorageReader *reader, T (&value)[N]) {
for (std::size_t i = 0; i < N; ++i) {
for (size_t i = 0; i < N; ++i) {
::Xsmp::Persist::Restore(simulator, reader, value[i]);
}
}
Expand Down Expand Up @@ -180,7 +180,7 @@ void Restore(const ::Smp::ISimulator *simulator, const ::Smp::IObject *sender,
::Smp::IStorageReader *reader, Args &...args) {

auto restore = [simulator, sender, reader](auto &value) {
std::size_t hash = 0;
size_t hash = 0;
Restore(simulator, reader, hash);
if (hash != typeid(value).hash_code()) {
::Xsmp::Exception::throwCannotRestore(sender, typeid(value).name());
Expand Down
Loading

0 comments on commit ba61ee8

Please sign in to comment.