13 #include <dpsim-models/Config.h>
14 #include <dpsim-models/Definitions.h>
15 #include <dpsim-models/MathUtils.h>
16 #include <dpsim-models/PtrFactory.h>
31 UPDATE_ON_SIMULATION_STEP,
34 template <
class T>
class Attribute;
36 template <
class T>
class AttributeStatic;
38 template <
class T>
class AttributeDynamic;
48 using element_type = T;
57 this->mPtr = ptr.getPtr();
63 this->mPtr = r.getPtr();
69 this->mPtr = r.getPtr();
74 this->mPtr = r.getPtr();
79 this->mPtr = r.getPtr();
83 T &operator*()
const noexcept {
return *mPtr; }
85 T *operator->()
const noexcept {
return mPtr.operator->(); }
87 T *get()
const {
return mPtr.get(); }
89 std::shared_ptr<T> getPtr()
const {
return mPtr; }
91 bool isNull()
const {
return mPtr ==
nullptr; }
118 std::shared_ptr<T> mPtr;
127 return a.getPtr() < b.getPtr();
137 return a.getPtr() == b.getPtr();
147 typedef std::vector<Ptr> List;
148 typedef std::set<Ptr, AttributeCmp<AttributeBase>> Set;
149 typedef std::map<String, Ptr> Map;
194 AttributeBase::Set deps = AttributeBase::Set();
206 typedef std::shared_ptr<AttributeUpdateTaskBase<DependentType>> Ptr;
208 virtual void executeUpdate(std::shared_ptr<DependentType> &dependent) = 0;
209 virtual AttributeBase::List getDependencies() = 0;
218 template <
class DependentType,
class... DependencyTypes>
222 AttributeUpdateTask<DependentType, DependencyTypes...>> {
226 std::function<void(std::shared_ptr<DependentType> &,
230 std::tuple<typename Attribute<DependencyTypes>::Ptr...> mDependencies;
231 Actor mActorFunction;
232 UpdateTaskKind mKind;
239 mActorFunction(actorFunction), mKind(kind) {}
242 executeUpdate(std::shared_ptr<DependentType> &dependent)
override {
253 [](
auto &&...elems) {
254 return std::vector<AttributeBase::Ptr>{
255 std::forward<decltype(elems)>(elems)...};
267 public std::enable_shared_from_this<Attribute<T>> {
270 std::shared_ptr<T> mData;
278 *mData = initialValue;
285 virtual void set(T value) = 0;
308 std::stringstream ss;
322 operator const T &() {
return this->
get(); }
335 std::dynamic_pointer_cast<Attribute<T>>(copyFrom.getPtr());
336 if (copyFromTyped.getPtr() ==
nullptr) {
339 this->
set(**copyFromTyped);
347 const std::type_info &
getType()
override {
return typeid(T); }
368 derive(
typename AttributeUpdateTask<U, T>::Actor getter =
369 typename AttributeUpdateTask<U, T>::Actor(),
370 typename AttributeUpdateTask<U, T>::Actor setter =
371 typename AttributeUpdateTask<U, T>::Actor()) {
372 auto derivedAttribute = std::make_shared<AttributeDynamic<U>>();
374 derivedAttribute->addTask(
375 UpdateTaskKind::UPDATE_ON_SET,
377 UpdateTaskKind::UPDATE_ON_SET, setter,
381 derivedAttribute->addTask(
382 UpdateTaskKind::UPDATE_ON_GET,
384 UpdateTaskKind::UPDATE_ON_GET, getter,
387 return derivedAttribute;
394 template <
typename U = T,
395 std::enable_if_t<std::is_same_v<Complex, U>,
bool> =
true>
399 AttributeUpdateTask<CPS::Real, CPS::Complex>::Actor getter =
400 [](std::shared_ptr<Real> &dependent,
402 *dependent = (**dependency).real();
404 AttributeUpdateTask<CPS::Real, CPS::Complex>::Actor setter =
405 [](std::shared_ptr<Real> &dependent,
407 CPS::Complex currentValue = dependency->get();
408 currentValue.real(*dependent);
409 dependency->set(currentValue);
411 return derive<CPS::Real>(getter, setter);
418 template <
typename U = T,
419 std::enable_if_t<std::is_same_v<Complex, U>,
bool> =
true>
423 AttributeUpdateTask<CPS::Real, CPS::Complex>::Actor getter =
424 [](std::shared_ptr<Real> &dependent,
426 *dependent = (**dependency).imag();
428 AttributeUpdateTask<CPS::Real, CPS::Complex>::Actor setter =
429 [](std::shared_ptr<Real> &dependent,
431 CPS::Complex currentValue = dependency->get();
432 currentValue.imag(*dependent);
433 dependency->set(currentValue);
435 return derive<CPS::Real>(getter, setter);
442 template <
typename U = T,
443 std::enable_if_t<std::is_same_v<Complex, U>,
bool> =
true>
447 AttributeUpdateTask<CPS::Real, CPS::Complex>::Actor getter =
448 [](std::shared_ptr<Real> &dependent,
450 *dependent = Math::abs(**dependency);
452 AttributeUpdateTask<CPS::Real, CPS::Complex>::Actor setter =
453 [](std::shared_ptr<Real> &dependent,
455 CPS::Complex currentValue = dependency->get();
456 dependency->set(Math::polar(*dependent, Math::phase(currentValue)));
458 return derive<CPS::Real>(getter, setter);
465 template <
typename U = T,
466 std::enable_if_t<std::is_same_v<Complex, U>,
bool> =
true>
470 AttributeUpdateTask<CPS::Real, CPS::Complex>::Actor getter =
471 [](std::shared_ptr<Real> &dependent,
473 *dependent = Math::phase(**dependency);
475 AttributeUpdateTask<CPS::Real, CPS::Complex>::Actor setter =
476 [](std::shared_ptr<Real> &dependent,
478 CPS::Complex currentValue = dependency->get();
479 dependency->set(Math::polar(Math::abs(currentValue), *dependent));
481 return derive<CPS::Real>(getter, setter);
489 template <
typename U = T, std::enable_if_t<std::is_same_v<Real, U> ||
490 std::is_same_v<Complex, U>,
495 typename AttributeUpdateTask<T, T>::Actor getter =
497 *dependent = scale * (**dependency);
499 typename AttributeUpdateTask<T, T>::Actor setter =
501 dependency->set((*dependent) / scale);
503 return derive<T>(getter, setter);
513 template <
class U,
class V = T,
514 std::enable_if_t<std::is_same_v<CPS::MatrixVar<U>, V>,
bool> =
true>
517 typename CPS::MatrixVar<U>::Index column)
520 typename AttributeUpdateTask<U, T>::Actor getter =
521 [row, column](std::shared_ptr<U> &dependent,
523 *dependent = (**dependency)(row, column);
525 typename AttributeUpdateTask<U, T>::Actor setter =
526 [row, column](std::shared_ptr<U> &dependent,
528 CPS::MatrixVar<U> currentValue = dependency->get();
529 currentValue(row, column) = *dependent;
530 dependency->set(currentValue);
532 return derive<U>(getter, setter);
548 virtual void set(T value)
override { *this->mData = value; };
550 virtual T &
get()
override {
return *this->mData; };
552 virtual bool isStatic()
const override {
return true; }
558 virtual std::shared_ptr<T>
asRawPointer()
override {
return this->mData; }
561 deps->insert(this->shared_from_this());
574 std::vector<typename AttributeUpdateTaskBase<T>::Ptr> updateTasksOnce;
575 std::vector<typename AttributeUpdateTaskBase<T>::Ptr> updateTasksOnGet;
576 std::vector<typename AttributeUpdateTaskBase<T>::Ptr> updateTasksOnSet;
587 typename AttributeUpdateTaskBase<T>::Ptr task) {
589 case UpdateTaskKind::UPDATE_ONCE:
590 updateTasksOnce.push_back(task);
592 task->executeUpdate(this->mData);
594 case UpdateTaskKind::UPDATE_ON_GET:
595 updateTasksOnGet.push_back(task);
597 case UpdateTaskKind::UPDATE_ON_SET:
598 updateTasksOnSet.push_back(task);
600 case UpdateTaskKind::UPDATE_ON_SIMULATION_STEP:
611 case UpdateTaskKind::UPDATE_ONCE:
612 updateTasksOnce.clear();
614 case UpdateTaskKind::UPDATE_ON_GET:
615 updateTasksOnGet.clear();
617 case UpdateTaskKind::UPDATE_ON_SET:
618 updateTasksOnSet.clear();
620 case UpdateTaskKind::UPDATE_ON_SIMULATION_STEP:
629 updateTasksOnce.clear();
630 updateTasksOnGet.clear();
631 updateTasksOnSet.clear();
635 typename AttributeUpdateTask<T, T>::Actor getter =
636 [](std::shared_ptr<T> &dependent,
638 dependent = dependency->asRawPointer();
641 if (reference->isStatic()) {
642 this->
addTask(UpdateTaskKind::UPDATE_ONCE,
646 this->
addTask(UpdateTaskKind::UPDATE_ON_GET,
648 UpdateTaskKind::UPDATE_ON_GET, getter, reference));
653 for (
typename AttributeUpdateTaskBase<T>::Ptr task : updateTasksOnGet) {
654 task->executeUpdate(this->mData);
659 virtual void set(T value)
override {
660 *this->mData = value;
661 for (
typename AttributeUpdateTaskBase<T>::Ptr task : updateTasksOnSet) {
662 task->executeUpdate(this->mData);
666 virtual T &
get()
override {
667 for (
typename AttributeUpdateTaskBase<T>::Ptr task : updateTasksOnGet) {
668 task->executeUpdate(this->mData);
673 virtual bool isStatic()
const override {
return false; }
681 deps->insert(this->shared_from_this());
683 AttributeBase::Set newDeps = AttributeBase::Set();
684 for (
typename AttributeUpdateTaskBase<T>::Ptr task : updateTasksOnce) {
685 AttributeBase::List taskDeps = task->getDependencies();
686 newDeps.insert(taskDeps.begin(), taskDeps.end());
689 for (
typename AttributeUpdateTaskBase<T>::Ptr task : updateTasksOnGet) {
690 AttributeBase::List taskDeps = task->getDependencies();
691 newDeps.insert(taskDeps.begin(), taskDeps.end());
694 for (
auto dependency : newDeps) {
695 dependency->appendDependencies(deps);
712 template <
typename T>
struct hash<CPS::AttributePointer<T>> {
714 return std::hash<std::shared_ptr<T>>()(x.getPtr());
virtual bool isStatic() const =0
virtual const std::type_info & getType()=0
Get the type of this attribute.
virtual bool copyValue(AttributeBase::Ptr copyFrom)=0
Copy the attribute value of copyFrom onto this attribute.
virtual String toString()=0
virtual AttributeBase::Set getDependencies() final
virtual void appendDependencies(AttributeBase::Set *deps)=0
virtual AttributeBase::Ptr cloneValueOntoNewAttribute()=0
Generates a new attribute of the same type and copies the current value in the heap....
void addTask(UpdateTaskKind kind, typename AttributeUpdateTaskBase< T >::Ptr task)
virtual std::shared_ptr< T > asRawPointer() override
virtual T & get() override
virtual void setReference(typename Attribute< T >::Ptr reference) override
virtual void appendDependencies(AttributeBase::Set *deps) override
void clearTasks(UpdateTaskKind kind)
virtual void set(T value) override
virtual bool isStatic() const override
AttributePointer< Attribute< T > > deriveScaled(T scale)
AttributePointer< Attribute< Real > > deriveMag()
AttributePointer< Attribute< U > > deriveCoeff(typename CPS::MatrixVar< U >::Index row, typename CPS::MatrixVar< U >::Index column)
virtual std::shared_ptr< T > asRawPointer()=0
AttributePointer< Attribute< Real > > derivePhase()
T & operator*()
User-defined dereference operator.
Attribute< U >::Ptr derive(typename AttributeUpdateTask< U, T >::Actor getter=typename AttributeUpdateTask< U, T >::Actor(), typename AttributeUpdateTask< U, T >::Actor setter=typename AttributeUpdateTask< U, T >::Actor())
AttributePointer< Attribute< Real > > deriveReal()
virtual void setReference(Attribute< T >::Ptr reference)=0
const std::type_info & getType() override
Get the type of this attribute.
virtual void set(T value)=0
String toString() override
Fallback method for all attribute types not covered by the specifications in Attribute....
AttributeBase::Ptr cloneValueOntoNewAttribute() override
Generates a new attribute of the same type and copies the current value in the heap....
bool copyValue(AttributeBase::Ptr copyFrom) override
Copy the attribute value of copyFrom onto this attribute.
AttributePointer< Attribute< Real > > deriveImag()
virtual void set(T value) override
virtual void appendDependencies(AttributeBase::Set *deps) override
virtual void setReference(typename Attribute< T >::Ptr reference) override
virtual bool isStatic() const override
virtual T & get() override
virtual std::shared_ptr< T > asRawPointer() override
virtual AttributeBase::List getDependencies() override