Initial release
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
// This file is part of VSTGUI. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this
|
||||
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "vstguibase.h"
|
||||
|
||||
#if VSTGUI_ENABLE_DEPRECATED_METHODS
|
||||
|
||||
#include "vstguidebug.h"
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
|
||||
namespace VSTGUI {
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/** @brief simple dependency between objects.
|
||||
@ingroup new_in_4_0
|
||||
|
||||
@details You can inject this implementation into CBaseObjects whenever you need other CBaseObjects to be informed about
|
||||
changes to that class instance. Note that you need to handle recursions yourself and that no reference counting is done
|
||||
and that you must make sure that the dependent objects are alife while added as dependent.
|
||||
*/
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
class [[deprecated("Please use listeners instead")]] IDependency
|
||||
{
|
||||
public:
|
||||
/** add a dependent object */
|
||||
virtual void addDependency (CBaseObject* obj);
|
||||
/** remove a dependent object. */
|
||||
virtual void removeDependency (CBaseObject* obj);
|
||||
/** notify dependent objects of change with message. */
|
||||
virtual void changed (IdStringPtr message);
|
||||
/** defer changes until later. can be nested. If you use this, you must make sure that all message pointers are valid the whole time. */
|
||||
virtual void deferChanges (bool state);
|
||||
|
||||
/** helper class to defer changes until instance is destroyed. */
|
||||
class DeferChanges
|
||||
{
|
||||
public:
|
||||
explicit DeferChanges (IDependency* dep) : dep (dep) { dep->deferChanges (true); }
|
||||
~DeferChanges () noexcept { dep->deferChanges (false); }
|
||||
protected:
|
||||
IDependency* dep;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
protected:
|
||||
IDependency () = default;
|
||||
virtual ~IDependency () noexcept;
|
||||
|
||||
static void rememberObject (CBaseObject* obj) { obj->remember (); }
|
||||
static void forgetObject (CBaseObject* obj) { obj->forget (); }
|
||||
|
||||
using DeferedChangesSet = std::set<IdStringPtr>;
|
||||
using DependentList = std::list<CBaseObject*>;
|
||||
|
||||
int32_t deferChangeCount {0};
|
||||
DeferedChangesSet deferedChanges;
|
||||
DependentList dependents;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
inline void IDependency::addDependency (CBaseObject* obj)
|
||||
{
|
||||
dependents.emplace_back (obj);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
inline void IDependency::removeDependency (CBaseObject* obj)
|
||||
{
|
||||
dependents.remove (obj);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
inline void IDependency::changed (IdStringPtr message)
|
||||
{
|
||||
if (deferChangeCount)
|
||||
{
|
||||
deferedChanges.emplace (message);
|
||||
}
|
||||
else if (dependents.empty () == false)
|
||||
{
|
||||
auto* This = dynamic_cast<CBaseObject*> (this);
|
||||
DependentList localList (dependents);
|
||||
std::for_each (localList.begin (), localList.end (), rememberObject);
|
||||
for (auto& obj : localList)
|
||||
obj->notify (This, message);
|
||||
std::for_each (localList.begin (), localList.end (), forgetObject);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
inline void IDependency::deferChanges (bool state)
|
||||
{
|
||||
if (state)
|
||||
{
|
||||
deferChangeCount++;
|
||||
}
|
||||
else if (--deferChangeCount == 0)
|
||||
{
|
||||
for (auto& msg : deferedChanges)
|
||||
changed (msg);
|
||||
deferedChanges.clear ();
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
inline IDependency::~IDependency () noexcept
|
||||
{
|
||||
vstgui_assert (dependents.empty ());
|
||||
}
|
||||
|
||||
} // VSTGUI
|
||||
|
||||
#endif // VSTGUI_ENABLE_DEPRECATED_METHODS
|
||||
Reference in New Issue
Block a user