3
Copyright (C) 2000,2001 Stefan Westerfeld
6
This library is free software; you can redistribute it and/or
7
modify it under the terms of the GNU Library General Public
8
License as published by the Free Software Foundation; either
9
version 2 of the License, or (at your option) any later version.
11
This library is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
Library General Public License for more details.
16
You should have received a copy of the GNU Library General Public License
17
along with this library; see the file COPYING.LIB. If not, write to
18
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19
Boston, MA 02111-1307, USA.
23
#include "artsbuilder.h"
27
#include "flowsystem.h"
28
#include "stdsynthmodule.h"
29
#include "dynamicrequest.h"
30
#include "dynamicskeleton.h"
31
#include "startupmanager.h"
34
#undef STRUCTURE_DEBUG
39
class StructureBuilder_impl : virtual public StructureBuilder_skel {
41
list<ObjectFactory> factories;
43
void addFactory(ObjectFactory factory);
44
Object createObject(StructureDesc structure);
45
ModuleDef createTypeInfo(StructureDesc structure);
48
REGISTER_IMPLEMENTATION(StructureBuilder_impl);
50
typedef DynamicSkeleton<SynthModule_skel> SynthModule_dskel;
52
class Structure_impl : virtual public SynthModule_dskel,
53
virtual public StdSynthModule {
55
list<Object> structureObjects;
58
Structure_impl(StructureDesc structure, list<ObjectFactory>& factories);
62
void process(long methodID, Buffer *request, Buffer *result);
65
void StructureBuilder_impl::addFactory(ObjectFactory factory)
67
factories.push_back(factory);
70
ModuleDef StructureBuilder_impl::createTypeInfo(StructureDesc structure)
75
/* convert structure to InterfaceDef id */
76
md.moduleName = id.name = structure.name();
77
id.inheritedInterfaces.push_back("Arts::SynthModule");
79
vector<StructurePortDesc> *ports = structure.ports();
80
vector<StructurePortDesc>::iterator pi;
81
for(pi = ports->begin(); pi != ports->end(); pi++)
83
const Arts::PortType& type = pi->type();
88
// This is a little tricky, as input ports (which are bringing data
89
// from outside into the structure) are saved as output ports (and
90
// output ports as input ports).
91
ad.flags = AttributeType(
92
((type.direction == input)?streamOut:streamIn) |
93
((type.connType == conn_stream)?attributeStream:attributeAttribute)
95
ad.type = type.dataType;
97
// TODO: dupe check with inherited interfaces (once interfaces get
99
id.attributes.push_back(ad);
103
md.interfaces.push_back(id);
109
static class StructureBuilderCleanUp : public StartupClass {
114
vector<long>::iterator i;
115
for(i = types.begin(); i != types.end(); i++)
116
Dispatcher::the()->interfaceRepo().removeModule(*i);
119
virtual ~StructureBuilderCleanUp() {}
120
} structureBuilderCleanUp;
123
Object StructureBuilder_impl::createObject(StructureDesc structure)
125
ModuleDef md = createTypeInfo(structure);
127
// FIXME: find some faster way of ensuring type consistency than creating
128
// the thing from scratch every time
129
structureBuilderCleanUp.types.push_back(Dispatcher::the()->interfaceRepo().insertModule(md));
130
Object obj = Object::_from_base(new Structure_impl(structure, factories));
134
Structure_impl::Structure_impl(StructureDesc structureDesc,
135
list<ObjectFactory>& factories)
136
: SynthModule_dskel(structureDesc.name())
138
map<long, Object> moduleMap;
139
vector<ModuleDesc> *modules = structureDesc.modules();
140
vector<ModuleDesc>::iterator mi;
142
// create each object
143
for(mi = modules->begin(); mi != modules->end(); mi++)
145
ModuleDesc& md = *mi;
147
#ifdef STRUCTBUILDER_DEBUG
148
cout << "create " << md.name() << endl;
150
Object o = Object::null(); //SubClass(md.name());
152
Object_skel *skel = 0;
153
skel = ObjectManager::the()->create(md.name());
154
if(skel) o = Object::_from_base(skel);
156
#ifdef STRUCTBUILDER_DEBUG
157
if(o.isNull()) cout << "no local creator for " << md.name() << endl;
159
list<ObjectFactory>::iterator fi = factories.begin();
160
while(o.isNull() && fi != factories.end())
162
o = fi->createObject(md.name());
166
#ifdef STRUCTBUILDER_DEBUG
167
if(o.isNull()) cout << "no remote creator for " << md.name() << endl;
170
moduleMap[md.ID()] = o;
171
structureObjects.push_back(o);
174
// connect objects and set values
175
for(mi = modules->begin(); mi != modules->end(); mi++)
177
Object& object = moduleMap[mi->ID()];
179
vector<PortDesc> *ports = mi->ports();
180
vector<PortDesc>::iterator pi;
182
for(pi = ports->begin(); pi != ports->end(); pi++)
185
const Arts::PortType& ptype = pd.type();
190
#ifdef STRUCTBUILDER_DEBUG
191
cout << "value " << mi->name() << "." << pi->name() << endl;
194
if(ptype.connType == conn_property)
196
DynamicRequest req(object);
197
req.method("_set_"+pi->name());
198
req.param(pd.value());
200
bool requestOk = req.invoke();
201
arts_assert(requestOk);
205
if(ptype.dataType == "float")
206
setValue(object,pi->name(),pd.floatValue());
208
arts_warning("unexpected property type %s",
209
ptype.dataType.c_str());
210
//setStringValue(object,pd.stringValue());
213
else if(pd.isConnected() && ptype.direction == output)
215
// create connections
217
vector<PortDesc> *connections = pd.connections();
218
vector<PortDesc>::iterator ci;
220
for(ci = connections->begin(); ci != connections->end(); ci++)
222
if(!ci->parent().isNull()) // structureport otherwise
224
Object& dest = moduleMap[ci->parent().ID()];
225
#ifdef STRUCTBUILDER_DEBUG
226
cout << "connect " << mi->name() << "." << pi->name()
227
<< " to " << ci->parent().name()
228
<< "." << ci->name() << endl;
230
connect(object,pd.name(),dest,ci->name());
240
// create ports (should be done via dynamic impl class...)
242
vector<StructurePortDesc> *ports = structureDesc.ports();
243
vector<StructurePortDesc>::iterator pi;
245
for(pi = ports->begin(); pi != ports->end(); pi++)
247
Arts::StructurePortDesc& pd = *pi;
250
// create connections
252
vector<PortDesc> *connections = pd.connections();
253
vector<PortDesc>::iterator ci;
255
for(ci = connections->begin(); ci != connections->end(); ci++)
257
Object& dest = moduleMap[ci->parent().ID()];
258
#ifdef STRUCTBUILDER_DEBUG
259
cout << "virtualize " << pi->name()
260
<< " to " << ci->parent().name() << "." << ci->name()
264
_node()->virtualize(pd.name(),dest._node(),ci->name());
272
void Structure_impl::streamInit()
274
list<Object>::iterator i;
276
#ifdef STRUCTBUILDER_DEBUG
277
cout << "vstructure: got streamInit()" << endl;
280
for(i=structureObjects.begin(); i != structureObjects.end(); i++)
282
if(i->_base()->_isCompatibleWith("Arts::SynthModule"))
287
void Structure_impl::streamEnd()
289
list<Object>::iterator i;
291
#ifdef STRUCTBUILDER_DEBUG
292
cout << "vstructure: got streamEnd()" << endl;
295
for(i=structureObjects.begin(); i != structureObjects.end(); i++)
296
if(i->_base()->_isCompatibleWith("Arts::SynthModule"))
300
void Structure_impl::process(long methodID, Buffer *request, Buffer *result)
302
const MethodDef& methodDef = getMethodDef(methodID);
303
arts_fatal("Structure_impl: unimplemented method, method ID=%ld name='%s'",
304
methodID, methodDef.name.c_str());