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); }
369 derive(
typename AttributeUpdateTask<U, T>::Actor getter =
370 typename AttributeUpdateTask<U, T>::Actor(),
371 typename AttributeUpdateTask<U, T>::Actor setter =
372 typename AttributeUpdateTask<U, T>::Actor()) {
373 auto derivedAttribute = std::make_shared<AttributeDynamic<U>>();
375 derivedAttribute->addTask(
376 UpdateTaskKind::UPDATE_ON_SET,
378 UpdateTaskKind::UPDATE_ON_SET, setter,
382 derivedAttribute->addTask(
383 UpdateTaskKind::UPDATE_ON_GET,
385 UpdateTaskKind::UPDATE_ON_GET, getter,
388 return derivedAttribute;
395 template <
typename U = T,
396 std::enable_if_t<std::is_same_v<Complex, U>,
bool> =
true>
400 AttributeUpdateTask<CPS::Real, CPS::Complex>::Actor getter =
401 [](std::shared_ptr<Real> &dependent,
403 *dependent = (**dependency).real();
405 AttributeUpdateTask<CPS::Real, CPS::Complex>::Actor setter =
406 [](std::shared_ptr<Real> &dependent,
408 CPS::Complex currentValue = dependency->get();
409 currentValue.real(*dependent);
410 dependency->set(currentValue);
412 return derive<CPS::Real>(getter, setter);
419 template <
typename U = T,
420 std::enable_if_t<std::is_same_v<Complex, U>,
bool> =
true>
424 AttributeUpdateTask<CPS::Real, CPS::Complex>::Actor getter =
425 [](std::shared_ptr<Real> &dependent,
427 *dependent = (**dependency).imag();
429 AttributeUpdateTask<CPS::Real, CPS::Complex>::Actor setter =
430 [](std::shared_ptr<Real> &dependent,
432 CPS::Complex currentValue = dependency->get();
433 currentValue.imag(*dependent);
434 dependency->set(currentValue);
436 return derive<CPS::Real>(getter, setter);
443 template <
typename U = T,
444 std::enable_if_t<std::is_same_v<Complex, U>,
bool> =
true>
448 AttributeUpdateTask<CPS::Real, CPS::Complex>::Actor getter =
449 [](std::shared_ptr<Real> &dependent,
451 *dependent = Math::abs(**dependency);
453 AttributeUpdateTask<CPS::Real, CPS::Complex>::Actor setter =
454 [](std::shared_ptr<Real> &dependent,
456 CPS::Complex currentValue = dependency->get();
457 dependency->set(Math::polar(*dependent, Math::phase(currentValue)));
459 return derive<CPS::Real>(getter, setter);
466 template <
typename U = T,
467 std::enable_if_t<std::is_same_v<Complex, U>,
bool> =
true>
471 AttributeUpdateTask<CPS::Real, CPS::Complex>::Actor getter =
472 [](std::shared_ptr<Real> &dependent,
474 *dependent = Math::phase(**dependency);
476 AttributeUpdateTask<CPS::Real, CPS::Complex>::Actor setter =
477 [](std::shared_ptr<Real> &dependent,
479 CPS::Complex currentValue = dependency->get();
480 dependency->set(Math::polar(Math::abs(currentValue), *dependent));
482 return derive<CPS::Real>(getter, setter);
490 template <
typename U = T, std::enable_if_t<std::is_same_v<Real, U> ||
491 std::is_same_v<Complex, U>,
496 typename AttributeUpdateTask<T, T>::Actor getter =
498 *dependent = scale * (**dependency);
500 typename AttributeUpdateTask<T, T>::Actor setter =
502 dependency->set((*dependent) / scale);
504 return derive<T>(getter, setter);
514 template <
class U,
class V = T,
515 std::enable_if_t<std::is_same_v<CPS::MatrixVar<U>, V>,
bool> =
true>
518 typename CPS::MatrixVar<U>::Index column)
521 typename AttributeUpdateTask<U, T>::Actor getter =
522 [row, column](std::shared_ptr<U> &dependent,
524 *dependent = (**dependency)(row, column);
526 typename AttributeUpdateTask<U, T>::Actor setter =
527 [row, column](std::shared_ptr<U> &dependent,
529 CPS::MatrixVar<U> currentValue = dependency->get();
530 currentValue(row, column) = *dependent;
531 dependency->set(currentValue);
533 return derive<U>(getter, setter);
549 virtual void set(T value)
override { *this->mData = value; };
551 virtual T &
get()
override {
return *this->mData; };
553 virtual bool isStatic()
const override {
return true; }
559 virtual std::shared_ptr<T>
asRawPointer()
override {
return this->mData; }
562 deps->insert(this->shared_from_this());
575 std::vector<typename AttributeUpdateTaskBase<T>::Ptr> updateTasksOnce;
576 std::vector<typename AttributeUpdateTaskBase<T>::Ptr> updateTasksOnGet;
577 std::vector<typename AttributeUpdateTaskBase<T>::Ptr> updateTasksOnSet;
588 typename AttributeUpdateTaskBase<T>::Ptr task) {
590 case UpdateTaskKind::UPDATE_ONCE:
591 updateTasksOnce.push_back(task);
593 task->executeUpdate(this->mData);
595 case UpdateTaskKind::UPDATE_ON_GET:
596 updateTasksOnGet.push_back(task);
598 case UpdateTaskKind::UPDATE_ON_SET:
599 updateTasksOnSet.push_back(task);
601 case UpdateTaskKind::UPDATE_ON_SIMULATION_STEP:
612 case UpdateTaskKind::UPDATE_ONCE:
613 updateTasksOnce.clear();
615 case UpdateTaskKind::UPDATE_ON_GET:
616 updateTasksOnGet.clear();
618 case UpdateTaskKind::UPDATE_ON_SET:
619 updateTasksOnSet.clear();
621 case UpdateTaskKind::UPDATE_ON_SIMULATION_STEP:
630 updateTasksOnce.clear();
631 updateTasksOnGet.clear();
632 updateTasksOnSet.clear();
636 typename AttributeUpdateTask<T, T>::Actor getter =
637 [](std::shared_ptr<T> &dependent,
639 dependent = dependency->asRawPointer();
642 if (reference->isStatic()) {
643 this->
addTask(UpdateTaskKind::UPDATE_ONCE,
647 this->
addTask(UpdateTaskKind::UPDATE_ON_GET,
649 UpdateTaskKind::UPDATE_ON_GET, getter, reference));
654 for (
typename AttributeUpdateTaskBase<T>::Ptr task : updateTasksOnGet) {
655 task->executeUpdate(this->mData);
660 virtual void set(T value)
override {
661 *this->mData = value;
662 for (
typename AttributeUpdateTaskBase<T>::Ptr task : updateTasksOnSet) {
663 task->executeUpdate(this->mData);
667 virtual T &
get()
override {
668 for (
typename AttributeUpdateTaskBase<T>::Ptr task : updateTasksOnGet) {
669 task->executeUpdate(this->mData);
674 virtual bool isStatic()
const override {
return false; }
682 deps->insert(this->shared_from_this());
684 AttributeBase::Set newDeps = AttributeBase::Set();
685 for (
typename AttributeUpdateTaskBase<T>::Ptr task : updateTasksOnce) {
686 AttributeBase::List taskDeps = task->getDependencies();
687 newDeps.insert(taskDeps.begin(), taskDeps.end());
690 for (
typename AttributeUpdateTaskBase<T>::Ptr task : updateTasksOnGet) {
691 AttributeBase::List taskDeps = task->getDependencies();
692 newDeps.insert(taskDeps.begin(), taskDeps.end());
695 for (
auto dependency : newDeps) {
696 dependency->appendDependencies(deps);
713 template <
typename T>
struct hash<CPS::AttributePointer<T>> {
715 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