2016-02-13 14:23:55 +01:00
|
|
|
/*
|
|
|
|
|
STATE-MAP-GROUPING-STORAGE.hpp - grouping storage to track presentation state
|
|
|
|
|
|
|
|
|
|
Copyright (C) Lumiera.org
|
|
|
|
|
2016, Hermann Vosseler <Ichthyostega@web.de>
|
|
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
|
modify it under the terms of the GNU General Public License as
|
|
|
|
|
published by the Free Software Foundation; either version 2 of
|
|
|
|
|
the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** @file state-map-grouping-storage.hpp
|
|
|
|
|
** Implementation of storage for captured presentation state.
|
|
|
|
|
** This is a associative storage, grouped by element ID.
|
|
|
|
|
**
|
2016-02-13 19:48:50 +01:00
|
|
|
** @see StateRecorder
|
|
|
|
|
** @see BusTerm_test::captureStateMark()
|
|
|
|
|
** @see BusTerm_test::replayStateMark()
|
2016-02-13 14:23:55 +01:00
|
|
|
**
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef GUI_INTERACT_STATE_MAP_GROUPING_STORAGE_H
|
|
|
|
|
#define GUI_INTERACT_STATE_MAP_GROUPING_STORAGE_H
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "lib/error.hpp"
|
2016-02-13 19:48:50 +01:00
|
|
|
#include "lib/idi/entry-id.hpp"
|
2016-02-13 14:23:55 +01:00
|
|
|
#include "lib/diff/gen-node.hpp"
|
|
|
|
|
|
|
|
|
|
#include <boost/noncopyable.hpp>
|
2016-02-13 16:30:32 +01:00
|
|
|
#include <unordered_map>
|
2016-02-13 19:48:50 +01:00
|
|
|
#include <set>
|
2016-02-13 14:23:55 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace gui {
|
|
|
|
|
namespace interact {
|
|
|
|
|
|
2016-02-13 16:30:32 +01:00
|
|
|
using lib::idi::BareEntryID;
|
|
|
|
|
using lib::diff::GenNode;
|
2016-02-13 19:48:50 +01:00
|
|
|
using lib::diff::Ref;
|
2016-02-13 14:23:55 +01:00
|
|
|
|
2016-02-13 16:30:32 +01:00
|
|
|
|
2016-02-13 14:23:55 +01:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Map storage for captured presentation state information.
|
2016-02-13 19:48:50 +01:00
|
|
|
* The master table is an association of model::Tangible element IDs
|
|
|
|
|
* to StateData records, which are a set of property data elements.
|
|
|
|
|
* The key of the stored elements acts as propertyKey and was chosen
|
|
|
|
|
* by the originating UI element. It is assumed that the entry last
|
|
|
|
|
* seen represents the current state of this property, so previous
|
|
|
|
|
* records are overwritten. Access to unknown data is marked by
|
|
|
|
|
* returning diff::Ref::NO rsp. `Storage::end()` (when searching)
|
2016-02-13 14:23:55 +01:00
|
|
|
*/
|
2016-02-13 19:48:50 +01:00
|
|
|
class StateMapGroupingStorage
|
2016-02-13 14:23:55 +01:00
|
|
|
: boost::noncopyable
|
|
|
|
|
{
|
2016-02-13 19:48:50 +01:00
|
|
|
using StateData = std::set<GenNode, GenNode::IDComparator>;
|
|
|
|
|
using Storage = std::unordered_map<BareEntryID, StateData, BareEntryID::UseEmbeddedHash>;
|
2016-02-13 16:30:32 +01:00
|
|
|
|
2016-02-13 17:09:57 +01:00
|
|
|
|
2016-02-13 19:48:50 +01:00
|
|
|
Storage elmTable_;
|
|
|
|
|
|
|
|
|
|
public:
|
2016-02-13 17:09:57 +01:00
|
|
|
using Record = Storage::value_type;
|
2016-02-13 16:30:32 +01:00
|
|
|
|
2016-02-13 19:48:50 +01:00
|
|
|
bool
|
|
|
|
|
empty() const
|
|
|
|
|
{
|
|
|
|
|
return elmTable_.empty();
|
|
|
|
|
}
|
2016-02-13 16:30:32 +01:00
|
|
|
|
2016-02-13 19:48:50 +01:00
|
|
|
size_t
|
|
|
|
|
size() const
|
|
|
|
|
{
|
|
|
|
|
size_t siz{0};
|
|
|
|
|
for (Record const& entry : elmTable_)
|
|
|
|
|
siz += entry.second.size();
|
|
|
|
|
return siz;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
clear()
|
|
|
|
|
{
|
|
|
|
|
elmTable_.clear();
|
|
|
|
|
}
|
2016-02-13 16:30:32 +01:00
|
|
|
|
2016-02-13 14:23:55 +01:00
|
|
|
|
2016-02-13 14:46:21 +01:00
|
|
|
/** retrieve captured state
|
|
|
|
|
* @return reference to the state mark last seen for the denoted property
|
|
|
|
|
* or reference to a generic "no" marker (Ref::NO)
|
|
|
|
|
*/
|
2016-02-13 16:30:32 +01:00
|
|
|
GenNode const&
|
|
|
|
|
retrieve (BareEntryID const& elementID, string propertyKey) const
|
|
|
|
|
{
|
2016-02-13 19:48:50 +01:00
|
|
|
iterator entry = find (elementID);
|
|
|
|
|
if (entry == elmTable_.end())
|
|
|
|
|
return Ref::NO;
|
|
|
|
|
else
|
|
|
|
|
return getState (*entry, propertyKey);
|
2016-02-13 16:30:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
record (BareEntryID const& elementID, GenNode const& stateMark)
|
|
|
|
|
{
|
2016-02-13 19:48:50 +01:00
|
|
|
elmTable_[elementID].emplace (stateMark);
|
2016-02-13 16:30:32 +01:00
|
|
|
}
|
|
|
|
|
|
2016-02-13 19:48:50 +01:00
|
|
|
|
2016-02-13 16:30:32 +01:00
|
|
|
using iterator = Storage::const_iterator;
|
|
|
|
|
|
|
|
|
|
iterator begin() const { return elmTable_.begin(); }
|
|
|
|
|
iterator end() const { return elmTable_.end(); }
|
|
|
|
|
|
|
|
|
|
iterator
|
2016-02-13 19:48:50 +01:00
|
|
|
find (BareEntryID const& elementID) const
|
2016-02-13 16:30:32 +01:00
|
|
|
{
|
2016-02-13 19:48:50 +01:00
|
|
|
return elmTable_.find (elementID);
|
2016-02-13 16:30:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static BareEntryID const&
|
2016-02-13 19:48:50 +01:00
|
|
|
getID (Record const& entry)
|
2016-02-13 16:30:32 +01:00
|
|
|
{
|
2016-02-13 17:09:57 +01:00
|
|
|
return entry.first;
|
2016-02-13 16:30:32 +01:00
|
|
|
}
|
|
|
|
|
|
2016-02-13 17:09:57 +01:00
|
|
|
static StateData const&
|
2016-02-13 19:48:50 +01:00
|
|
|
getState (Record const& entry)
|
2016-02-13 16:30:32 +01:00
|
|
|
{
|
2016-02-13 17:09:57 +01:00
|
|
|
return entry.second;
|
2016-02-13 16:30:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static GenNode const&
|
2016-02-13 19:48:50 +01:00
|
|
|
getState (Record const& entry, string propertyKey)
|
2016-02-13 14:46:21 +01:00
|
|
|
{
|
2016-02-13 19:48:50 +01:00
|
|
|
StateData const& stateSet = entry.second;
|
|
|
|
|
StateData::const_iterator propertyRecord = stateSet.find (propertyKey);
|
|
|
|
|
if (propertyRecord == stateSet.end())
|
|
|
|
|
return Ref::NO;
|
|
|
|
|
else
|
|
|
|
|
return *propertyRecord;
|
2016-02-13 14:46:21 +01:00
|
|
|
}
|
2016-02-13 14:23:55 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}} // namespace gui::interact
|
|
|
|
|
#endif /*GUI_INTERACT_STATE_MAP_GROUPING_STORAGE_H*/
|