LUMIERA.clone/src/proc/mobject/session/sess-manager-impl.cpp

290 lines
8.9 KiB
C++
Raw Normal View History

/*
SessManagerImpl - global session access and lifecycle
2010-12-17 23:28:49 +01:00
Copyright (C) Lumiera.org
2008, Hermann Vosseler <Ichthyostega@web.de>
2010-12-17 23:28:49 +01:00
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
2010-12-17 23:28:49 +01:00
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.
2010-12-17 23:28:49 +01:00
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.
2010-12-17 23:28:49 +01:00
* *****************************************************/
/** @file sess-manager-impl.cpp
** Implementation of the Session management functions.
** The Class SessManager is declared alongside with mobject::Session,
** because it serves as smart ptr-to-Impl at the same time. Effectively,
** the session manager owns the current session object and only grants
** access via his overloaded operator->() . Because there is no operator*(),
** no one can get at the address of the current session object. (correct?)
**
** TODO: this is an implementation draft, awaiting integration with several other facilities //////////////////TICKET #704
**
** @see session-impl.hpp
** @see mobject::Session#current
** @see mobject::session::SessionManager_test
**
*/
#include "proc/mobject/session.hpp"
#include "proc/mobject/session/sess-manager-impl.hpp"
#include "proc/mobject/session/defs-manager.hpp"
#include "proc/mobject/session/lifecycle-advisor.hpp"
2010-10-24 06:50:00 +02:00
#include "proc/asset/timeline.hpp"
#include "lib/error.hpp"
2010-10-24 06:50:00 +02:00
#include "lib/query.hpp"
using boost::scoped_ptr;
2010-10-24 06:50:00 +02:00
namespace mobject {
namespace session {
LUMIERA_ERROR_DEFINE (CREATE_SESSION, "unable to create basic session");
/** Access to the "current session", which actually is
* an SessionImpl instance. This session object is created
* either by loading an existing session, or on demand by
* this accessor function here (when no session was loaded
* or created)
* @note any exceptions arising while building the basic
* session object(s) will halt the system.
*/
SessionImplAPI*
SessManagerImpl::operator-> () throw()
{
if (!pImpl_)
try
{ // create empty default configured session
this->reset();
}
catch (...)
{
ERROR (progress, "Unrecoverable Failure while creating the empty default session.");
throw lumiera::error::Fatal ( "Failure while creating the basic session object. System halted."
, LUMIERA_ERROR_CREATE_SESSION );
}
return pImpl_.get();
}
2010-10-24 02:48:00 +02:00
namespace { // defining details of the Session Lifecycle
typedef scoped_ptr<SessionImplAPI> SessionPImpl;
class SessionLifecycleDetails
: public LifecycleAdvisor
{
SessionPImpl & session_;
2010-10-24 06:50:00 +02:00
bool shall_load_; ////////////TODO a placeholder; later we'll pass in a de-serialiser
2010-10-24 02:48:00 +02:00
2010-10-24 06:50:00 +02:00
/** @note Any session services get up into default configured state.
* After the swap, \c tmpS holds onto the old session, which
* consequently should unwind on leaving this scope. */
2010-10-24 02:48:00 +02:00
void
createSessionFacilities()
{
INFO (session, "Initialising new Session....");
2010-10-24 06:50:00 +02:00
SessionPImpl tmpS (new SessionImplAPI);
session_.swap (tmpS);
2010-10-24 02:48:00 +02:00
}
void
injectSessionContent()
{
2010-10-24 06:50:00 +02:00
if (shall_load_)
{
UNIMPLEMENTED ("loading session from persistent storage");
}
else
{ // inject some default session content
REQUIRE (0 == session_->timelines.size(), "injecting default timeline, but session isn't pristine");
// issue a default query to retrieve or create a Timeline and a default Sequence
2010-10-24 06:50:00 +02:00
asset::PTimeline initialTimeline = session_->defaults (lumiera::Query<asset::Timeline> ());
// these got registered automatically
ENSURE (1 == session_->timelines.size());
ENSURE (initialTimeline == session_->timelines[0]);
2010-10-24 06:50:00 +02:00
}
2010-10-24 02:48:00 +02:00
}
void
getSessionReady()
{
INFO (session, "Session ready for use.");
2010-10-24 02:48:00 +02:00
}
void
openSessionInterface()
{
TODO ("open public session interface"); /////////////////////// TICKET #699
2010-10-24 02:48:00 +02:00
}
void
closeSessionInterface()
{ /////////////////////// TICKET #699
INFO (session, "closing session interfaces.");
TODO ("actually close session interfaces :) and don't babble in the log when NOT closing anything...");
2010-10-24 02:48:00 +02:00
}
void
disconnectRenderProcesses()
{
TODO ("halt rendering"); //////////////////////////////////////// TICKET #703
TODO ("possibly terminate builder"); ////////////////////////////// TICKET #201
2010-10-24 02:48:00 +02:00
}
void
commandLogCheckpoint()
{ //////////////////////////////////////// TICKET #697
INFO (command, " Session shutdown. Command processing stopped.");
2010-10-24 02:48:00 +02:00
}
void
deconfigure()
{
2010-10-24 06:50:00 +02:00
TODO ("reset the assets registered with AssetManager");
/////////////////////////////////////////////////////////////////// TICKET #154
2010-10-24 02:48:00 +02:00
}
public:
SessionLifecycleDetails(SessionPImpl& currentSessionAccessPoint)
: session_(currentSessionAccessPoint)
2010-10-24 06:50:00 +02:00
, shall_load_(false)
{ }
};
}//(End) details of Session Lifecycle
/** Starting up the session access and lifecycle management.
* Initially (at static init time), only the single system-wide
* Session manger instance is created. It can be used to load an
* existing session; otherwise an empty default Session, together
* with the core facilities (PlacementIndex, AssetManager, Query
* subsystem and the Defaults manager) is created on first
* \link #operator-> access \endlink to the session object.
*/
SessManagerImpl::SessManagerImpl () throw()
: pImpl_ (0)
, lifecycle_(new SessionLifecycleDetails(pImpl_))
{
Session::initFlag = true; //////////////////////////////////////// TICKET #518 instead of this hack, implement basic-init of the session manager for real
}
SessManagerImpl::~SessManagerImpl ()
{
TODO ("verify sane lifecycle");
Session::initFlag = false;
}
bool
SessManagerImpl::isUp ()
{
2010-10-24 06:50:00 +02:00
return bool(pImpl_); ///////////////////// TICKET #702 possible race, because this gets true way before the interface is up
}
/** @note no transactional behaviour. may succeed partially.
* @todo clarify relation to command processing/undo /////////// TICKET #697
*/
void
SessManagerImpl::clear ()
{
2010-10-24 06:50:00 +02:00
Lock sync(this);
pImpl_->clear();
}
/** Shut down the current session together with all associated services.
* @todo avoid blocking when aborting render processes ///////////// TICKET #201
* @todo well defined transactional behaviour ///////////////////// TICKET #698
*/
void
SessManagerImpl::close ()
{
2010-10-24 06:50:00 +02:00
Lock sync(this);
lifecycle_->shutDown();
pImpl_.reset();
}
/** @todo error handling, how to deal with a partially configured session?
* @todo for \c reset() to work, we need to change the implementation of
* AssetManager so support this kind of transactional switch!
*/
void
SessManagerImpl::reset ()
{
2010-10-24 06:50:00 +02:00
Lock sync(this);
lifecycle_->shutDown();
lifecycle_->pullUp();
}
void
SessManagerImpl::load ()
{
UNIMPLEMENTED ("load serialised session");
2010-10-24 06:50:00 +02:00
Lock sync(this);
lifecycle_->shutDown();
lifecycle_->pullUp();
}
/** \par Implementation details
* We intend to have several switchable object serialisers.
* One of these serialisers should generate a comprehensible
* text based representation suitable for checking into
* SCM systems.
* Sessions can be saved into one single file or be split
* to several files (master file and edl files)
*/
void
SessManagerImpl::save ()
{
UNIMPLEMENTED ("save session (serialised)");
2010-10-24 06:50:00 +02:00
/////////////////////////////////////////////////TODO: need lock?
}
}} // namespace mobject::session