~ubuntu-branches/ubuntu/hoary/kdemultimedia/hoary

« back to all changes in this revision

Viewing changes to arts/runtime/structurebuilder_impl.cc

  • Committer: Bazaar Package Importer
  • Author(s): Martin Schulze
  • Date: 2003-01-22 15:00:51 UTC
  • Revision ID: james.westby@ubuntu.com-20030122150051-uihwkdoxf15mi1tn
Tags: upstream-2.2.2
ImportĀ upstreamĀ versionĀ 2.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
    /*
 
2
 
 
3
    Copyright (C) 2000,2001 Stefan Westerfeld
 
4
                            stefan@space.twc.de
 
5
 
 
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.
 
10
  
 
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.
 
15
   
 
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.
 
20
 
 
21
    */
 
22
 
 
23
#include "artsbuilder.h"
 
24
#include "artsflow.h"
 
25
#include "connect.h"
 
26
#include "debug.h"
 
27
#include "flowsystem.h"
 
28
#include "stdsynthmodule.h"
 
29
#include "dynamicrequest.h"
 
30
#include "dynamicskeleton.h"
 
31
#include "startupmanager.h"
 
32
#include <list>
 
33
 
 
34
#undef STRUCTURE_DEBUG
 
35
 
 
36
using namespace Arts;
 
37
using namespace std;
 
38
 
 
39
class StructureBuilder_impl : virtual public StructureBuilder_skel {
 
40
protected:
 
41
        list<ObjectFactory> factories;
 
42
public:
 
43
        void addFactory(ObjectFactory factory);
 
44
        Object createObject(StructureDesc structure);
 
45
        ModuleDef createTypeInfo(StructureDesc structure);
 
46
};
 
47
 
 
48
REGISTER_IMPLEMENTATION(StructureBuilder_impl);
 
49
 
 
50
typedef DynamicSkeleton<SynthModule_skel> SynthModule_dskel;
 
51
 
 
52
class Structure_impl : virtual public SynthModule_dskel,
 
53
                       virtual public StdSynthModule {
 
54
protected:
 
55
        list<Object> structureObjects;
 
56
 
 
57
public:
 
58
        Structure_impl(StructureDesc structure, list<ObjectFactory>& factories);
 
59
        void streamInit();
 
60
        void streamEnd();
 
61
 
 
62
        void process(long methodID, Buffer *request, Buffer *result);
 
63
};
 
64
 
 
65
void StructureBuilder_impl::addFactory(ObjectFactory factory)
 
66
{
 
67
        factories.push_back(factory);
 
68
}
 
69
 
 
70
ModuleDef StructureBuilder_impl::createTypeInfo(StructureDesc structure)
 
71
{
 
72
        ModuleDef md;
 
73
        InterfaceDef id;
 
74
 
 
75
/* convert structure to InterfaceDef id */
 
76
        md.moduleName = id.name = structure.name();
 
77
        id.inheritedInterfaces.push_back("Arts::SynthModule");
 
78
 
 
79
        vector<StructurePortDesc> *ports = structure.ports();
 
80
        vector<StructurePortDesc>::iterator pi;
 
81
        for(pi = ports->begin(); pi != ports->end(); pi++)
 
82
        {
 
83
                const Arts::PortType& type = pi->type();
 
84
 
 
85
                AttributeDef ad;
 
86
                ad.name = pi->name();
 
87
 
 
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)
 
94
                );
 
95
                ad.type = type.dataType;
 
96
 
 
97
                // TODO: dupe check with inherited interfaces (once interfaces get
 
98
                // inherited)
 
99
                id.attributes.push_back(ad);
 
100
        }
 
101
        delete ports;
 
102
 
 
103
        md.interfaces.push_back(id);
 
104
 
 
105
        return md;
 
106
}
 
107
 
 
108
namespace Arts {
 
109
static class StructureBuilderCleanUp : public StartupClass {
 
110
public:
 
111
        vector<long> types;
 
112
        void startup() { };
 
113
        void shutdown() {
 
114
                vector<long>::iterator i;
 
115
                for(i = types.begin(); i != types.end(); i++)
 
116
                        Dispatcher::the()->interfaceRepo().removeModule(*i);
 
117
                types.clear();
 
118
        }
 
119
        virtual ~StructureBuilderCleanUp() {}
 
120
} structureBuilderCleanUp;
 
121
};
 
122
 
 
123
Object StructureBuilder_impl::createObject(StructureDesc structure)
 
124
{
 
125
        ModuleDef md = createTypeInfo(structure);
 
126
 
 
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));
 
131
        return obj;
 
132
}
 
133
 
 
134
Structure_impl::Structure_impl(StructureDesc structureDesc,
 
135
                                                                        list<ObjectFactory>& factories)
 
136
        : SynthModule_dskel(structureDesc.name())
 
137
{
 
138
        map<long, Object> moduleMap;
 
139
        vector<ModuleDesc> *modules = structureDesc.modules();
 
140
        vector<ModuleDesc>::iterator mi;
 
141
 
 
142
        // create each object
 
143
        for(mi = modules->begin(); mi != modules->end(); mi++)
 
144
        {
 
145
                ModuleDesc& md = *mi;
 
146
 
 
147
#ifdef STRUCTBUILDER_DEBUG
 
148
                cout << "create " << md.name() << endl;
 
149
#endif
 
150
                Object o = Object::null(); //SubClass(md.name());
 
151
 
 
152
                Object_skel *skel = 0;
 
153
                skel = ObjectManager::the()->create(md.name());
 
154
                if(skel) o = Object::_from_base(skel);
 
155
 
 
156
#ifdef STRUCTBUILDER_DEBUG
 
157
                if(o.isNull()) cout << "no local creator for " << md.name() << endl;
 
158
#endif
 
159
                list<ObjectFactory>::iterator fi = factories.begin();
 
160
                while(o.isNull() && fi != factories.end())
 
161
                {
 
162
                        o = fi->createObject(md.name());
 
163
                        fi++;
 
164
                }
 
165
 
 
166
#ifdef STRUCTBUILDER_DEBUG
 
167
                if(o.isNull()) cout << "no remote creator for " << md.name() << endl;
 
168
#endif
 
169
                assert(!o.isNull());
 
170
                moduleMap[md.ID()] = o;
 
171
                structureObjects.push_back(o);
 
172
        }
 
173
 
 
174
        // connect objects and set values
 
175
        for(mi = modules->begin(); mi != modules->end(); mi++)
 
176
        {
 
177
                Object& object = moduleMap[mi->ID()];
 
178
 
 
179
                vector<PortDesc> *ports = mi->ports();
 
180
                vector<PortDesc>::iterator pi;
 
181
 
 
182
                for(pi = ports->begin(); pi != ports->end(); pi++)
 
183
                {
 
184
                        PortDesc& pd = *pi;
 
185
                        const Arts::PortType& ptype = pd.type();
 
186
 
 
187
                        if(pd.hasValue())
 
188
                        {
 
189
                                // set values
 
190
#ifdef STRUCTBUILDER_DEBUG
 
191
                                cout << "value " << mi->name() << "." << pi->name() << endl;
 
192
#endif
 
193
 
 
194
                                if(ptype.connType == conn_property)
 
195
                                {
 
196
                                        DynamicRequest req(object);
 
197
                                        req.method("_set_"+pi->name());
 
198
                                        req.param(pd.value());
 
199
 
 
200
                                        bool requestOk = req.invoke();
 
201
                                        arts_assert(requestOk);
 
202
                                }
 
203
                                else
 
204
                                {
 
205
                                        if(ptype.dataType == "float")
 
206
                                                setValue(object,pi->name(),pd.floatValue());
 
207
                                        else
 
208
                                                arts_warning("unexpected property type %s",     
 
209
                                                                                                        ptype.dataType.c_str());
 
210
                                                //setStringValue(object,pd.stringValue());
 
211
                                }
 
212
                        }
 
213
                        else if(pd.isConnected() && ptype.direction == output)
 
214
                        {
 
215
                                // create connections
 
216
 
 
217
                                vector<PortDesc> *connections = pd.connections();
 
218
                                vector<PortDesc>::iterator ci;
 
219
 
 
220
                                for(ci = connections->begin(); ci != connections->end(); ci++)
 
221
                                {
 
222
                                        if(!ci->parent().isNull())      // structureport otherwise
 
223
                                        {
 
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;
 
229
#endif
 
230
                                                connect(object,pd.name(),dest,ci->name());
 
231
                                        }
 
232
                                }
 
233
                                delete connections;
 
234
                        }
 
235
                }
 
236
                delete ports;
 
237
        }
 
238
        delete modules;
 
239
 
 
240
        // create ports (should be done via dynamic impl class...)
 
241
 
 
242
        vector<StructurePortDesc> *ports = structureDesc.ports();
 
243
        vector<StructurePortDesc>::iterator pi;
 
244
 
 
245
        for(pi = ports->begin(); pi != ports->end(); pi++)
 
246
        {
 
247
                Arts::StructurePortDesc& pd = *pi;
 
248
                if(pd.isConnected())
 
249
                {
 
250
                        // create connections
 
251
 
 
252
                        vector<PortDesc> *connections = pd.connections();
 
253
                        vector<PortDesc>::iterator ci;
 
254
 
 
255
                        for(ci = connections->begin(); ci != connections->end(); ci++)
 
256
                        {
 
257
                                Object& dest = moduleMap[ci->parent().ID()];
 
258
#ifdef STRUCTBUILDER_DEBUG
 
259
                                cout << "virtualize " << pi->name()
 
260
                                     << " to " << ci->parent().name() << "." << ci->name()
 
261
                                         << endl;
 
262
#endif
 
263
 
 
264
                                _node()->virtualize(pd.name(),dest._node(),ci->name());
 
265
                        }
 
266
                        delete connections;
 
267
                }
 
268
        }
 
269
        delete ports;
 
270
}
 
271
 
 
272
void Structure_impl::streamInit()
 
273
{
 
274
        list<Object>::iterator i;
 
275
 
 
276
#ifdef STRUCTBUILDER_DEBUG
 
277
        cout << "vstructure: got streamInit()" << endl;
 
278
#endif
 
279
 
 
280
        for(i=structureObjects.begin(); i != structureObjects.end(); i++)
 
281
        {
 
282
                if(i->_base()->_isCompatibleWith("Arts::SynthModule"))
 
283
                        i->_node()->start();
 
284
        }
 
285
}
 
286
 
 
287
void Structure_impl::streamEnd()
 
288
{
 
289
        list<Object>::iterator i;
 
290
 
 
291
#ifdef STRUCTBUILDER_DEBUG
 
292
        cout << "vstructure: got streamEnd()" << endl;
 
293
#endif
 
294
 
 
295
        for(i=structureObjects.begin(); i != structureObjects.end(); i++)
 
296
                if(i->_base()->_isCompatibleWith("Arts::SynthModule"))
 
297
                        i->_node()->stop();
 
298
}
 
299
 
 
300
void Structure_impl::process(long methodID, Buffer *request, Buffer *result)
 
301
{
 
302
        const MethodDef& methodDef = getMethodDef(methodID);
 
303
        arts_fatal("Structure_impl: unimplemented method, method ID=%ld name='%s'",
 
304
                                methodID, methodDef.name.c_str());
 
305
}