implement a stack of ScopePath frames
This commit is contained in:
parent
665eed5f1b
commit
d90812e64b
3 changed files with 135 additions and 2 deletions
|
|
@ -26,12 +26,17 @@
|
|||
|
||||
//#include "proc/mobject/mobject.hpp"
|
||||
//#include "proc/mobject/placement.hpp"
|
||||
#include "proc/mobject/session/scope-path.hpp"
|
||||
|
||||
//#include <vector>
|
||||
//#include <string>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <list>
|
||||
|
||||
//using std::vector;
|
||||
//using std::string;
|
||||
using std::list;
|
||||
|
||||
|
||||
namespace mobject {
|
||||
namespace session {
|
||||
|
|
@ -42,13 +47,117 @@ namespace session {
|
|||
* TODO type comment
|
||||
*/
|
||||
class QueryFocusStack
|
||||
: boost::noncopyable
|
||||
{
|
||||
|
||||
public:
|
||||
std::list<ScopePath> paths_;
|
||||
|
||||
public:
|
||||
QueryFocusStack()
|
||||
: paths_()
|
||||
{
|
||||
openDefaultFrame();
|
||||
}
|
||||
|
||||
|
||||
bool empty() const;
|
||||
size_t size() const;
|
||||
|
||||
ScopePath& push (Scope const&);
|
||||
ScopePath& top ();
|
||||
void pop_unused ();
|
||||
|
||||
|
||||
private:
|
||||
void openDefaultFrame();
|
||||
};
|
||||
///////////////////////////TODO currently just fleshing the API
|
||||
|
||||
|
||||
bool
|
||||
QueryFocusStack::empty() const
|
||||
{
|
||||
return paths_.empty();
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
QueryFocusStack::size() const
|
||||
{
|
||||
return paths_.size();
|
||||
}
|
||||
|
||||
|
||||
/** Open a new path frame, pushing down the current frame.
|
||||
* The new frame tries to locate the given start scope
|
||||
* and navigates to this position.
|
||||
* @note EXCEPTION_STRONG guarantee
|
||||
* @return reference to the newly created path on top
|
||||
* @throw error::Invalid if newStartPoint isn't locatable
|
||||
*/
|
||||
ScopePath&
|
||||
QueryFocusStack::push (Scope const& newStartPoint)
|
||||
{
|
||||
ScopePath newPathFrame (newStartPoint); // may throw
|
||||
ENSURE (newPathFrame.isValid() || newStartPoint.isRoot());
|
||||
|
||||
paths_.push_back (newPathFrame);
|
||||
ENSURE (0 < size());
|
||||
return paths_.back();
|
||||
}
|
||||
|
||||
|
||||
/** @return the topmost path frame actually in use
|
||||
* @note may invoke #pop_unused()
|
||||
* @note EXCEPTON_FREE ///////TODO prove!
|
||||
*/
|
||||
ScopePath&
|
||||
QueryFocusStack::top ()
|
||||
{
|
||||
if ( 0 == size()
|
||||
|| 0 == paths_.back().ref_count()
|
||||
)
|
||||
pop_unused();
|
||||
|
||||
ENSURE (!empty());
|
||||
ENSURE (!paths_.back().empty());
|
||||
return paths_.back();
|
||||
}
|
||||
|
||||
|
||||
/** investigate the stack top and discard any path frames
|
||||
* which aren't referred anymore (as indicated by their
|
||||
* ScopePath#use_count(). After executing this function
|
||||
* the topmost frame is either in use, or a new default
|
||||
* frame has been created at the bottom of an empty stack.
|
||||
* @note EXCEPTON_FREE ///////TODO prove!
|
||||
*/
|
||||
void
|
||||
QueryFocusStack::pop_unused ()
|
||||
{
|
||||
while (size() && (0 == paths_.back().ref_count()))
|
||||
paths_.pop_back();
|
||||
|
||||
if (0 == size())
|
||||
openDefaultFrame();
|
||||
ENSURE (!empty());
|
||||
ENSURE (!paths_.back().empty());
|
||||
}
|
||||
|
||||
|
||||
/** @internal open a default path frame at the bottom
|
||||
* of an empty stack, locating to current model root
|
||||
* @note EXCEPTON_FREE ///////TODO prove!
|
||||
*/
|
||||
void
|
||||
QueryFocusStack::openDefaultFrame()
|
||||
{
|
||||
REQUIRE (0 == size());
|
||||
paths_.resize(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}} // namespace mobject::session
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
* *****************************************************/
|
||||
|
||||
|
||||
#include "include/logging.h"
|
||||
#include "proc/mobject/session/scope-path.hpp"
|
||||
#include "proc/mobject/session/scope-locator.hpp"
|
||||
#include "proc/mobject/session/session-service-explore-scope.hpp"
|
||||
|
|
@ -113,7 +114,7 @@ namespace session {
|
|||
|
||||
ScopePath::~ScopePath()
|
||||
{
|
||||
WARN_IF (refcount_, "Destroying a scope path frame with ref-count=%u", refcount_);
|
||||
WARN_IF (refcount_, session, "Destroying a scope path frame with ref-count=%lu", refcount_);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -149,6 +149,9 @@ namespace session {
|
|||
|
||||
friend bool operator== (ScopePath const&, ScopePath const&);
|
||||
|
||||
friend void intrusive_ptr_add_ref (ScopePath*);
|
||||
friend void intrusive_ptr_release (ScopePath*);
|
||||
|
||||
|
||||
/* == mutations == */
|
||||
void clear();
|
||||
|
|
@ -182,6 +185,26 @@ namespace session {
|
|||
}
|
||||
|
||||
|
||||
/** management function for boost::intrusive_ptr
|
||||
* to be picked up by ADL
|
||||
*/
|
||||
void
|
||||
intrusive_ptr_add_ref (ScopePath* pathFrame)
|
||||
{
|
||||
REQUIRE (pathFrame);
|
||||
++(pathFrame->refcount_);
|
||||
}
|
||||
|
||||
void
|
||||
intrusive_ptr_release (ScopePath* pathFrame)
|
||||
{
|
||||
REQUIRE (pathFrame);
|
||||
if (0 < pathFrame->refcount_)
|
||||
--(pathFrame->refcount_);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline size_t
|
||||
ScopePath::ref_count() const
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue