diff --git a/src/proc/asset.cpp b/src/proc/asset.cpp index 901f21d4e..1fb15ce47 100644 --- a/src/proc/asset.cpp +++ b/src/proc/asset.cpp @@ -52,7 +52,7 @@ namespace asset * concrete subclasses are created via specialized Factories */ Asset::Asset (const Ident& idi) - : ident(idi), id(AssetManager::reg (this, idi)) + : ident(idi), id(AssetManager::reg (this, idi)), disabled(false) { TRACE (assetmem, "ctor Asset(id=%lu) : adr=%x %s", size_t(id), this, cStr(this->ident) ); } @@ -77,6 +77,36 @@ namespace asset } + //////////////////////////////////////////////////////////TODO: factor this out as library function + + template + inline bool + and_all (SEQ& coll, Oper predicate) + { + typename SEQ::const_iterator e = coll.end(); + typename SEQ::const_iterator i = coll.begin(); + + while (i!=e && predicate(*i)) ++i; + return i==e; + } + + template + inline const V* + deref (const shared_ptr& ptr) + { + return ptr.get(); + } + + //////////////////////////////////////////////////////////TODO: factor this out as library function + + + bool + all_parents_enabled (const vector& parents) + { + return and_all (parents, bind (&Asset::isActive, + bind (&deref,_1) )); //////////TODO: possibly define an operator-> + } + /** * whether this asset is swithced on and consequently included * in the fixture and participates in rendering. @@ -84,19 +114,29 @@ namespace asset bool Asset::isActive () const { - UNIMPLEMENTED ("enable/disable Assets."); + return !this->disabled + && all_parents_enabled (parents); } - - /** - * change the enablement status of this asset. - * @note the corresponding #isActive predicate may depend - * on the enablement status of parent assets as well. - */ + void + propagate_down (PAsset child, bool on) + { + child->enable(on); + } + + + /**change the enablement status of this asset. */ + bool Asset::enable (bool on) throw(cinelerra::error::State) { - UNIMPLEMENTED ("enable/disable Assets."); + if (on != this->disabled) + return true; + if (on && !all_parents_enabled (parents)) + return false; + disabled = !on; + for_each (dependants, bind (&propagate_down, _1 ,on)); + return true; ////////TODO?? } diff --git a/src/proc/asset.hpp b/src/proc/asset.hpp index 11f18c85a..e915067a7 100644 --- a/src/proc/asset.hpp +++ b/src/proc/asset.hpp @@ -215,6 +215,8 @@ namespace asset vector parents; vector dependants; + + bool disabled; @@ -275,8 +277,10 @@ namespace asset /** change the enabled status of this asset. * Note the corresponding #isActive predicate may * depend on the enablement status of parent assets as well + * @return \c false if the state could not be changed + * due to parent objects being disabled */ - void enable (bool on=true) throw(cinelerra::error::State); + bool enable (bool on=true) throw(cinelerra::error::State); }; diff --git a/tests/components/proc/asset/dependantassetstest.cpp b/tests/components/proc/asset/dependantassetstest.cpp index b5bb82671..52611b692 100644 --- a/tests/components/proc/asset/dependantassetstest.cpp +++ b/tests/components/proc/asset/dependantassetstest.cpp @@ -55,7 +55,7 @@ namespace asset checkDependencyMechanics (); checkUnlinking (); TODO ("activate missing testcases"); -/////TODO checkEnablementPropagation (); + checkEnablementPropagation (); /////TODO checkRealAssetDependencyRegistration (); } @@ -125,7 +125,8 @@ namespace asset void checkEnablementPropagation () { PAsset a1 = TA::create(); - PAsset a2 = TA::create(a1); + PTestA a2_= TA::create(a1); + PAsset a2 (a2_); PAsset a3 = TA::create(); // not dependant ASSERT (a1->isActive()); @@ -162,6 +163,28 @@ namespace asset ASSERT (!a1->isActive()); ASSERT (!a2->isActive()); ASSERT (a3->isActive()); + + a1->enable(); + a2_->set_depend(a3); // now add a new parent dependency + a3->enable(false); + ASSERT (a1->isActive()); + ASSERT (!a2->isActive()); // has been propagated via the new dependency + ASSERT (!a3->isActive()); + + a2->enable(true); + ASSERT (a1->isActive()); // no change because one of the parents is disbled + ASSERT (!a2->isActive()); + ASSERT (!a3->isActive()); + a1->enable(false); + ASSERT (!a1->isActive()); + a3->enable(true); + ASSERT (!a1->isActive()); // no propagation because the disabled other parent (a1) + ASSERT (!a2->isActive()); + ASSERT (a3->isActive()); + a1->enable(true); + ASSERT (a1->isActive()); // but now propagation is possible + ASSERT (a2->isActive()); + ASSERT (a3->isActive()); }