/* Struct(Asset) - key abstraction: structural asset Copyright (C) Lumiera.org 2008, Hermann Vosseler 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. * *****************************************************/ #include "proc/asset/struct.hpp" #include "proc/assetmanager.hpp" #include "proc/config-resolver.hpp" #include "proc/asset/struct-factory-impl.hpp" #include "lib/util.hpp" #include "lib/symbol.hpp" #include "lib/query-util.hpp" #include "include/logging.h" #include "common/query.hpp" #include using boost::format; using lib::Symbol; using lib::query::normaliseID; using lumiera::query::QueryHandler; using proc::ConfigResolver; using util::contains; namespace proc { namespace asset { /****** NOTE: not fully implemented yet. What follows is partially a hack to build simple tests *******/ /** storage for the static StructFactory instance */ StructFactory Struct::retrieve; /** using private implementation detail class */ StructFactory::StructFactory () : impl_(new StructFactoryImpl(*this)) { } /** invoke the factory to create new Structural Asset. * This function skips the query and retrieval of existing * instances and immediately creates a new one. * @param nameID (optional) an ID to use; if omitted an ID * will be default created, based on the kind of Asset. * @throw error::Invalid in case of ID clash with an existing Asset * @return an Struct smart ptr linked to the internally registered smart ptr * created as a side effect of calling the concrete Struct subclass ctor. * @todo using the AssetManager this way for picking up the previously stored * asset is a code smell ////////////////////////////TICKET #691 */ template lib::P StructFactory::newInstance (Symbol nameID) { Query desired_name (isnil(nameID)? "" : "id("+nameID+")"); STRU* pS = impl_->fabricate (desired_name); return AssetManager::instance().wrap (*pS); } /** Retrieve a suitable Structural Asset instance, possibly create one. * First tries to resolve the asset by issuing an capability query. * If unsuccessful, use some internally specialised ctor call. * @todo work out the struct asset naming scheme! /////////////////////////////////TICKET #565 * @todo for now we're using a faked config query, just pulling preconfigured * hardwired answers from a table. Should be replaced by a real resolution engine. * @note the exact calling sequence implemented here can be considered a compromise, * due to having neither a working resolution, nor a generic interface for * issuing queries. Thus, directly calling this factory acts as a replacement * for both. The intended solution would be to have a dedicated QueryResolver, * which is fully integrated into a generic rules driven query subsystem, but * has the additional ability to "translate" capabilities directly into the * respective properties of of asset::Struct subclasses. * @return a Struct smart ptr linked to the internally registered smart ptr * created as a side effect of calling the concrete Struct subclass ctor. */ template lib::P StructFactory::operator() (Query const& capabilities) { lib::P res; QueryHandler& typeHandler = ConfigResolver::instance(); typeHandler.resolve (res, capabilities); if (res) return res; // create new one, since the // ConfigQuery didn't yield any result STRU* pS = impl_->fabricate(capabilities); return AssetManager::instance().wrap (*pS); } ////////////////////////////////////////////////////////////////////////////////////TICKET #710 : backdoor for fake-configrules /** special backdoor for fake-configrules.hpp * This allows to simulate creation of objects triggered by rules. * Actually we use just a fake implementation based on a table lookup * plus some hard wired special cases, which need to call in here to * fabricate new objects, which can then be used as "solutions". * @param query a prolog like query string * @note works quite similar like the #operator(), but without * re-invoking the ConfigRules.... */ template lib::P StructFactory::made4fake (Query const& query) { STRU* pS = impl_->fabricate(query); return AssetManager::instance().wrap (*pS); } ////////////////////////////////////////////////////////////////////////////////////TICKET #710 : backdoor for fake-configrules /** Factory method for creating Pipes explicitly. * Normalises pipe- and streamID, then retrieves the * default processing pattern (ProcPatt) for this streamID. * The Pipe ctor will fill out the shortDesc and longDesc * automatically, based on pipeID and streamID (and they * are editable anyways) * @see ProcPatt * @see DefaultsManager */ lib::P StructFactory::newPipe (string pipeID, string streamID) { normaliseID (pipeID); normaliseID (streamID); static format descriptor("pipe(%s), stream(%s)."); Pipe* pP = impl_->fabricate (Query (str(descriptor % pipeID % streamID))); return AssetManager::instance().wrap (*pP); } }} // namespace asset /**************************************************/ /* explicit instantiations of the factory methods */ /**************************************************/ #include "proc/asset/pipe.hpp" #include "proc/asset/procpatt.hpp" #include "proc/asset/timeline.hpp" #include "proc/asset/sequence.hpp" namespace proc { namespace asset { using PPipe = lib::P; template PPipe StructFactory::operator() (Query const&); template PProcPatt StructFactory::operator() (Query const&); template PTimeline StructFactory::operator() (Query const&); template PSequence StructFactory::operator() (Queryconst&); template PPipe StructFactory::newInstance (Symbol); template PProcPatt StructFactory::newInstance (Symbol); template PTimeline StructFactory::newInstance (Symbol); template PSequence StructFactory::newInstance (Symbol); template PPipe StructFactory::made4fake (Query const&); template PProcPatt StructFactory::made4fake (Query const&); template PTimeline StructFactory::made4fake (Query const&); template PSequence StructFactory::made4fake (Queryconst&); }} // namespace asset