first steps towards using the new SessionServices access mechanism

add the necessary hooks and change the SessionImpl accordingly.
Still using the old access method for any real code
This commit is contained in:
Fischlurch 2009-11-09 07:35:08 +01:00
parent 79d5e49a74
commit 7da8844581
14 changed files with 418 additions and 180 deletions

View file

@ -197,7 +197,11 @@ namespace mobject {
return false;
}
ExplicitPlacement resolve() const { return access(id_).resolve();}
ExplicitPlacement
resolve() const
{
return access(id_).resolve();
}
////////////////TODO more operations to come....

View file

@ -97,7 +97,7 @@ namespace mobject {
public:
static session::SessManager& current;
session::DefsManager& defaults;
session::DefsManager& defaults; ///////////////TODO this is a hack... better solve it based on the new SessionServices mechanism
virtual bool isValid () = 0;
virtual void add (PMO& placement) = 0;

View file

@ -57,12 +57,9 @@ namespace mobject {
{
scoped_ptr<impl::DefsRegistry> defsRegistry;
protected:
public:
DefsManager () throw();
friend class SessManagerImpl;
public:
~DefsManager ();
/** common access point: retrieve the default object fulfilling

View file

@ -1,5 +1,5 @@
/*
PLACEMENT-INDEX.hpp - tracking individual Placements and their relations
PLACEMENT-INDEX-QUERY-RESOLVER.hpp - using PlacementIndex to resolve scope queries
Copyright (C) Lumiera.org
2009, Hermann Vosseler <Ichthyostega@web.de>
@ -21,7 +21,8 @@
*/
/** @file placement-index.hpp
/** @file placement-index-query-resolver.hpp
** TODO WIP-WIP
**
** @see PlacementRef
** @see PlacementIndex_test
@ -30,182 +31,45 @@
#ifndef MOBJECT_PLACEMENT_INDEX_H
#define MOBJECT_PLACEMENT_INDEX_H
#ifndef MOBJECT_SESSION_PLACEMENT_INDEX_QUERY_RESOLVER_H
#define MOBJECT_SESSION_PLACEMENT_INDEX_QUERY_RESOLVER_H
//#include "pre.hpp"
//#include "proc/mobject/session/locatingpin.hpp"
//#include "proc/asset/pipe.hpp"
#include "lib/util.hpp"
#include "lib/factory.hpp"
#include "proc/mobject/placement.hpp"
#include "proc/mobject/placement-ref.hpp"
//#include "lib/util.hpp"
//#include "lib/factory.hpp"
//#include "proc/mobject/placement.hpp"
#include "proc/mobject/session/placement-index.hpp"
#include "proc/mobject/session/query-resolver.hpp"
#include <tr1/memory>
#include <boost/noncopyable.hpp>
#include <boost/scoped_ptr.hpp>
#include <vector>
//#include <tr1/memory>
//#include <boost/noncopyable.hpp>
//#include <boost/scoped_ptr.hpp>
//#include <vector>
namespace mobject {
class MObject;
// class MObject; /////////////////////////////////////????
namespace session {
using lib::factory::RefcountFac;
using std::tr1::shared_ptr;
using boost::scoped_ptr;
using std::vector;
// using lib::factory::RefcountFac;
// using std::tr1::shared_ptr;
// using boost::scoped_ptr;
// using std::vector;
/**
* TODO type comment
*/
class PlacementIndex
: public session::QueryResolver ////////TODO: really inherit here?
// , boost::noncopyable ////////TODO : where to put the "noncopyable" base
class PlacementIndexQueryResolver
: public session::QueryResolver
{
class Table;
scoped_ptr<Table> pTab_;
public:
typedef Placement<MObject> PlacementMO;
typedef PlacementRef<MObject> PRef;
typedef PlacementMO::ID const& ID;
typedef session::Goal::QueryID const& QID;
PlacementMO& find (ID) const;
template<class MO>
Placement<MO>& find (PlacementMO::Id<MO>) const;
template<class MO>
Placement<MO>& find (PlacementRef<MO> const&) const;
PlacementMO& getScope (PlacementMO const&) const;
PlacementMO& getScope (ID) const;
vector<PRef> getReferrers (ID) const;
/** retrieve the logical root scope */
PlacementMO& getRoot() const;
size_t size() const;
bool contains (PlacementMO const&) const;
bool contains (ID) const;
////////////////////////////////////////////////////////////////TODO: refactor into explicit query resolving wrapper
template<class MO>
typename session::Query<Placement<MO> >::iterator
query (PlacementMO& scope) const;
operator string() const { return "PlacementIndex"; }
////////////////////////////////////////////////////////////////TODO: refactor into explicit query resolving wrapper
bool canHandleQuery(QID) const;
/* == mutating operations == */
ID insert (PlacementMO& newObj, PlacementMO& targetScope);
bool remove (PlacementMO&);
bool remove (ID);
typedef RefcountFac<PlacementIndex> Factory;
static Factory create;
~PlacementIndex();
void clear();
protected:
PlacementIndex() ;
friend class lib::factory::Factory<PlacementIndex, lib::factory::Wrapper<PlacementIndex, shared_ptr<PlacementIndex> > >;
};
////////////////TODO currently just fleshing out the API; probably have to split off an impl.class; but for now a PImpl is sufficient...
typedef shared_ptr<PlacementIndex> PPIdx;
/** @internal there is an implicit PlacementIndex available on a global scale,
* by default implemented within the current session. This function allows
* to re-define this implicit index temporarily, e.g. for unit tests. */
void
reset_PlacementIndex(PPIdx const&) ;
/** @internal restore the implicit PlacementIndex to its default implementation (=the session) */
void
reset_PlacementIndex() ;
/** @internal access point for PlacementRef to the implicit global PlacementIndex */
Placement<MObject> &
fetch_PlacementIndex(Placement<MObject>::ID const&) ;
/* === forwarding implementations of the templated API === */
template<class MO>
inline Placement<MO>&
PlacementIndex::find (PlacementMO::Id<MO> id) const
{
PlacementMO& result (find (id));
REQUIRE (INSTANCEOF (MO, &result) );
return static_cast<Placement<MO>&> (result);
}
template<class MO>
inline Placement<MO>&
PlacementIndex::find (PlacementRef<MO> const& pRef) const
{
PlacementMO::Id<MO> id (pRef);
return find (id);
}
/** @todo use query-resolver-test as an example.....
* return a result set object derived from Resolution
* For the additional type filtering: build a filter iterator,
* using a type-filtering predicate, based on Placement#isCompatible
*/
template<class MO>
inline typename session::Query<Placement<MO> >::iterator
PlacementIndex::query (PlacementMO& scope) const
{
UNIMPLEMENTED ("actually run the containment query");
}
inline Placement<MObject>&
PlacementIndex::getScope (PlacementMO const& p) const
{
return getScope(p.getID());
}
inline bool
PlacementIndex::contains (PlacementMO const& p) const
{
return contains (p.getID());
}
inline bool
PlacementIndex::remove (PlacementMO& p)
{
return remove (p.getID());
}
}} // namespace mobject::session

View file

@ -59,7 +59,7 @@ namespace session {
* @note any exceptions arising while building the basic
* session object(s) will halt the system.
*/
SessionImpl*
SessionImplAPI*
SessManagerImpl::operator-> () throw()
{
if (!pImpl_)
@ -87,8 +87,7 @@ namespace session {
* \link #operator-> access \endlink to the session object.
*/
SessManagerImpl::SessManagerImpl () throw()
: pDefs_ (0),
pImpl_ (0)
: pImpl_ (0)
{ }
@ -111,14 +110,12 @@ namespace session {
void
SessManagerImpl::reset ()
{
scoped_ptr<DefsManager> tmpD (new DefsManager);
scoped_ptr<SessionImpl> tmpS (new SessionImpl (*tmpD));
scoped_ptr<SessionImplAPI> tmpS (new SessionImplAPI);
TODO ("reset the assets registered with AssetManager");
/////////////////////////////////////////////////////////////////// TICKET #154
TODO ("thread lock");
pDefs_.swap (tmpD);
pImpl_.swap (tmpS);
}

View file

@ -28,13 +28,26 @@
namespace mobject {
namespace session {
/////////////////////////////////////////TODO temporary hack
namespace {
DefsManager&
getDummyDefaultsManager()
{
static scoped_ptr<DefsManager> dummyDefaultsManagerInstance(new DefsManager);
return *dummyDefaultsManagerInstance;
}
}
/////////////////////////////////////////TODO temporary hack
/** create a new empty session with default values.
* @note any exception arising while creating this
* default session will inevitably halt the
* system (and this is desirable)
*/
SessionImpl::SessionImpl (DefsManager& defs) throw()
: Session(defs),
SessionImpl::SessionImpl ()
: Session( getDummyDefaultsManager() ), ///////TODO temporary hack
focusEDL_(0),
edls(1),
fixture(new Fixture),

View file

@ -42,6 +42,13 @@
#include "proc/mobject/session/edl.hpp"
#include "proc/mobject/session/fixture.hpp"
#include "proc/mobject/session/placement-index.hpp"
#include "proc/mobject/session/session-services.hpp"
#include "proc/mobject/session/session-service-fetch.hpp"
#include "proc/mobject/session/session-service-explore-scope.hpp"
#include "proc/mobject/session/session-service-mock-index.hpp"
#include "proc/mobject/session/session-service-defaults.hpp"
#include <boost/scoped_ptr.hpp>
#include <vector>
@ -65,8 +72,12 @@ namespace session {
uint focusEDL_;
vector<EDL> edls;
PFix fixture;
shared_ptr<PlacementIndex> pIdx_;
scoped_ptr<DefsManager> defaultsManager_; ///////////TODO: later, this will be the real defaults manager. Currently this is just never initialised (11/09)
/* ==== Session API ==== */
virtual bool isValid ();
virtual void add (PMO& placement);
@ -78,7 +89,7 @@ namespace session {
virtual void rebuildFixture ();
protected: /* == management API === */
SessionImpl (DefsManager&) throw();
SessionImpl ();
friend class SessManagerImpl;
void clear ();
@ -86,6 +97,76 @@ namespace session {
};
/* ===== providing internal services for Proc ===== */
template<class IMPL>
struct ServiceAccessPoint<SessionServiceFetch, IMPL>
: IMPL
{
bool
isRegisteredID (PMO::ID const& placementID)
{
UNIMPLEMENTED ("check if index contains the given ID");
}
PMO&
resolveID (PMO::ID const& placementID)
{
UNIMPLEMENTED ("fetch from PlacementIndex, throw on failure");
// IMPL::implementationService();
}
};
template<class IMPL>
struct ServiceAccessPoint<SessionServiceExploreScope, IMPL>
: IMPL
{
QueryResolver&
getResolver()
{
UNIMPLEMENTED ("how actually to manage the PlacementIndexQueryResolver wrapper instance");
// return IMPL::magic_;
}
};
template<class IMPL>
struct ServiceAccessPoint<SessionServiceMockIndex, IMPL>
: IMPL
{
////////////////////////////TODO
};
template<class IMPL>
struct ServiceAccessPoint<SessionServiceDefaults, IMPL>
: IMPL
// , SessionServiceDefaults
{
////////////////////////////TODO
};
class SessManagerImpl;
typedef SessionServices< Types< SessionServiceFetch
, SessionServiceExploreScope
, SessionServiceMockIndex
, SessionServiceDefaults
> // List of the APIs to provide
, SessManagerImpl // frontend for access
, SessionImpl // implementation base class
> //
SessionImplAPI;
/**
* Session manager implementation class holding the
* actual smart pointer to the current Session impl.
@ -93,8 +174,7 @@ namespace session {
*/
class SessManagerImpl : public SessManager
{
scoped_ptr<DefsManager> pDefs_;
scoped_ptr<SessionImpl> pImpl_;
scoped_ptr<SessionImplAPI> pImpl_;
SessManagerImpl() throw();
friend class lib::singleton::StaticCreate<SessManagerImpl>;
@ -106,14 +186,15 @@ namespace session {
virtual void reset () ;
virtual void load () ;
virtual void save () ;
virtual SessionImpl* operator-> () throw() ;
public:
/* ==== proc layer internal API ==== */
/** @internal access point for PlacementIndex and PlacementRef */
static shared_ptr<PlacementIndex>& getCurrentIndex () ;
static shared_ptr<PlacementIndex>& getCurrentIndex () ;
virtual SessionImplAPI* operator-> () throw() ;
};

View file

@ -0,0 +1,59 @@
/*
SESSION-SERVICE-DEFAULTS.hpp - session implementation service API: manage default objects
Copyright (C) Lumiera.org
2008, 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 session-service-defaults.hpp
** Implementation level session API: manage default configured objects.
**
** @todo rework the existing DefsManager to fit into this scheme. TICKET #404
**
** @see session-impl.hpp implementation of the service
** @see session-services.cpp implementation of access
**
*/
#ifndef MOBJECT_SESSION_SESSION_SERVICE_DEFAULTS_H
#define MOBJECT_SESSION_SESSION_SERVICE_DEFAULTS_H
//#include "proc/mobject/session.hpp"
//#include "lib/meta/generator.hpp"
namespace mobject {
namespace session {
// using lumiera::typelist::InstantiateChained;
// using lumiera::typelist::InheritFrom;
// using lumiera::typelist::NullType;
class SessionServiceDefaults
{
};
}} // namespace mobject::session
#endif

View file

@ -0,0 +1,71 @@
/*
SESSION-SERVICE-EXPLORE-SCOPE.hpp - session implementation service API: explore scope
Copyright (C) Lumiera.org
2008, 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 session-service-explore-scope.hpp
** Implementation level session API: query a scope.
** This specialised service is intended to be used by the Scope and
** QueryFocus framework for enumerating objects contained within a
** given scope and for locating the scope's parent scope. Basically,
** this service just exposes a QueryResolver, which is actually
** backed by the PlacementIndex and is able to handle queries of
** type ScopeQuery, especially ContentsQuery and PathQuery.
**
** By virtue of this service, QueryFocus, Scope and Placement can
** remain completely agnostic of session's implementation details,
** and especially aren't bound to PlacementIndex. This is important,
** because the public session API is casted in terms of PlacementRef
** and QueryFocus An implementation of this service is available
** through the SessionServices access mechanism.
**
** @see session-impl.hpp implementation of the service
** @see session-services.cpp implementation of access
**
*/
#ifndef MOBJECT_SESSION_SESSION_SERVICE_EXPLORE_SCOPE_H
#define MOBJECT_SESSION_SESSION_SERVICE_EXPLORE_SCOPE_H
#include "proc/mobject/session/query-resolver.hpp"
//#include "lib/meta/generator.hpp"
namespace mobject {
namespace session {
// using lumiera::typelist::InstantiateChained;
// using lumiera::typelist::InheritFrom;
// using lumiera::typelist::NullType;
struct SessionServiceExploreScope
{
static QueryResolver& getResolver();
};
}} // namespace mobject::session
#endif

View file

@ -0,0 +1,64 @@
/*
SESSION-SERVICE-FETCH.hpp - session implementation service API: fetch PlacementRef
Copyright (C) Lumiera.org
2008, 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 session-service-fetch.hpp
** Implementation level session API: resolve a Placement by hash-ID.
** This specialised service is intended to be used by PlacementRef,
** in order to (re)-access the Placement instance within the session,
** given the hash-ID of this placement. An implementation of this
** service is available through the SessionServices access mechanism.
**
** @see session-impl.hpp implementation of the service
** @see session-services.cpp implementation of access
**
*/
#ifndef MOBJECT_SESSION_SESSION_SERVICE_FETCH_H
#define MOBJECT_SESSION_SESSION_SERVICE_FETCH_H
//#include "proc/mobject/session.hpp"
//#include "lib/meta/generator.hpp"
#include "proc/mobject/placement.hpp"
namespace mobject {
namespace session {
// using lumiera::typelist::InstantiateChained;
// using lumiera::typelist::InheritFrom;
// using lumiera::typelist::NullType;
class SessionServiceFetch
{
static PlacementMO& resolveID (PlacementMO::ID const&) ;
static bool isRegisteredID (PlacementMO::ID const&) ;
};
}} // namespace mobject::session
#endif

View file

@ -0,0 +1,62 @@
/*
SESSION-SERVICE-MOCK-INDEX.hpp - session service API: mock PlacementIndex for tests
Copyright (C) Lumiera.org
2008, 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 session-service-mock-index.hpp
** Implementation level session API: PlacementIndex mock for tests.
** Allows (temporarily) to replace the real Placement index within
** the session by a mock instance handed in through this API. Unit
** tests may use this \em backdoor to set up a specially prepared
** index to verify the behaviour of Placement and Scope resolution
** operations.
**
** @see session-impl.hpp implementation of the service
** @see session-services.cpp implementation of access
**
*/
#ifndef MOBJECT_SESSION_SESSION_SERVICE_MOCK_INDEX_H
#define MOBJECT_SESSION_SESSION_SERVICE_MOCK_INDEX_H
//#include "proc/mobject/session.hpp"
//#include "lib/meta/generator.hpp"
namespace mobject {
namespace session {
// using lumiera::typelist::InstantiateChained;
// using lumiera::typelist::InheritFrom;
// using lumiera::typelist::NullType;
class SessionServiceMockIndex
{
};
}} // namespace mobject::session
#endif

View file

@ -21,6 +21,11 @@
* *****************************************************/
#include "proc/mobject/session/session-service-fetch.hpp"
#include "proc/mobject/session/session-service-explore-scope.hpp"
#include "proc/mobject/session/session-service-mock-index.hpp"
#include "proc/mobject/session/session-service-defaults.hpp"
#include "proc/mobject/session/session-services.hpp"
#include "proc/mobject/session/session-impl.hpp"
@ -28,6 +33,18 @@ namespace mobject {
namespace session {
/** TODO */
bool
SessionServiceFetch::isRegisteredID (PlacementMO::ID const& placementID)
{
return SessionImplAPI::current->isRegisteredID (placementID);
}
PlacementMO&
SessionServiceFetch::resolveID (PlacementMO::ID const& placementID)
{
return SessionImplAPI::current->resolveID (placementID);
}

View file

@ -86,8 +86,7 @@ namespace mobject {
namespace session {
using lumiera::typelist::InstantiateChained;
using lumiera::typelist::InheritFrom;
using lumiera::typelist::NullType;
using lumiera::typelist::Types;
/**
@ -117,7 +116,7 @@ namespace session {
, class FRONT
, class SESS
>
class TSessionServices
class SessionServices
: public InstantiateChained< typename APIS::List // for each of the API types...
, ServiceAccessPoint // instantiate a service implementation
, SESS // and stack all these on top of SessionImpl

View file

@ -43,6 +43,7 @@ using lib::Symbol;
using lib::Singleton;
using mobject::session::SessManager;
using mobject::session::SessManagerImpl;
using mobject::session::SessionImplAPI;
namespace mobject {
@ -58,6 +59,15 @@ namespace mobject {
SessManager& Session::current = Singleton<SessManagerImpl>()();
/** special access point allowing Proc-Layer internals
* to cooperate with session implementation level APIs
*/
template<>
SessManagerImpl& SessionImplAPI::current = static_cast<SessManagerImpl&> (Session::current);
/** \par
* LifecycleHook, to perform all the basic setup for a new session,
* prior to adding any specific data, configuration or content. Any subsystems