LUMIERA.clone/src/proc/asset/structfactoryimpl.hpp

183 lines
5.3 KiB
C++

/*
STRUCTFACTORYIMPL.hpp - crating structural assets (impl details)
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 structfactoryimpl.hpp
** Private implementation details of creating various structural assets.
** @internal to be used by struct.cpp
**
** @see ConfigQuery
**
*/
#ifndef ASSET_STRUCTFACTORYIMPL_H
#define ASSET_STRUCTFACTORYIMPL_H
#include "proc/mobject/session.hpp"
#include "common/configrules.hpp"
#include "include/error.hpp"
#include "common/util.hpp"
#include <boost/format.hpp>
using boost::format;
using mobject::Session;
using util::isnil;
using util::contains;
using asset::Query;
using lumiera::query::LUMIERA_ERROR_CAPABILITY_QUERY;
using lumiera::query::extractID;
namespace asset
{
template<class STRU>
struct Traits
{
static Symbol namePrefix;
static Symbol catFolder;
static Symbol idSymbol;
};
template<> Symbol Traits<Track>::namePrefix = "track";
template<> Symbol Traits<Track>::catFolder = "tracks";
template<> Symbol Traits<Track>::idSymbol = "track";
template<> Symbol Traits<Pipe>::namePrefix = "pipe";
template<> Symbol Traits<Pipe>::catFolder = "pipes";
template<> Symbol Traits<Pipe>::idSymbol = "pipe";
template<> Symbol Traits<const ProcPatt>::namePrefix = "patt";
template<> Symbol Traits<const ProcPatt>::catFolder = "build-templates";
template<> Symbol Traits<const ProcPatt>::idSymbol = "procPatt";
/**
* Implementation deatils, esp. concerning how configuration
* queries are resolved and when to create new objects automatically.
* @todo better use a general struct traits class, esp.for creating the Ident
*/
class StructFactoryImpl
{
/** @internal derive a sensible asset ident tuple when creating
* structural asset instances based on a capability query
*/
template<class STRU>
const Asset::Ident
createIdent (const Query<STRU>& query)
{
string name (query);
string nameID = extractID (Traits<STRU>::idSymbol, query);
if (isnil (nameID))
{
// no name-ID contained in the query...
// so we'll create a new one
static int i=0;
static format namePattern ("%s.%d");
static format predPattern ("%s(%s), ");
nameID = str(namePattern % Traits<STRU>::namePrefix % (++i) );
name.insert(0,
str(predPattern % Traits<STRU>::idSymbol % nameID ));
}
ENSURE (!isnil (name));
ENSURE (!isnil (nameID));
ENSURE (contains (name, nameID));
Category cat (STRUCT, Traits<STRU>::catFolder);
return Asset::Ident (name, cat );
}
/** used for issuing recursive create calls to top level */
StructFactory& recursive_create_;
public:
StructFactoryImpl (StructFactory& interface)
: recursive_create_(interface)
{ }
/** make a new structural asset instance.
* default/fallback impl. throws.
*/
template<class STRU>
STRU* fabricate (const Query<STRU>& caps)
{
throw lumiera::error::Config ( str(format("The following Query could not be resolved: %s.") % caps.asKey())
, LUMIERA_ERROR_CAPABILITY_QUERY );
}
};
/* ============= specialisations =========================== */
template<>
Track*
StructFactoryImpl::fabricate (const Query<Track>& caps)
{
TODO ("actually extract properties/capabilities from the query...");
TODO ("make sure AssetManager detects dublicates (currently 4/08 it doesn't)");
return new Track (createIdent (caps));
}
template<>
const ProcPatt*
StructFactoryImpl::fabricate (const Query<const ProcPatt>& caps)
{
TODO ("actually extract properties/capabilities from the query...");
return new ProcPatt (createIdent (caps));
}
template<>
Pipe*
StructFactoryImpl::fabricate (const Query<Pipe>& caps)
{
const Asset::Ident idi (createIdent (caps));
string pipeID = extractID ("pipe", idi.name);
string streamID = extractID ("stream", caps);
if (isnil (streamID)) streamID = "default";
PProcPatt processingPattern = Session::current->defaults (Query<const ProcPatt>("stream("+streamID+")"));
return new Pipe( idi
, processingPattern
, pipeID
);
}
} // namespace asset
#endif