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

« back to all changes in this revision

Viewing changes to arts/runtime/structures_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
#include "artsbuilder.h"
 
2
#include "weakreference.h"
 
3
#include "sequenceutils.h"
 
4
#include "moduleinfo.h"
 
5
#include "compatibility.h"
 
6
#include <stdio.h>
 
7
#include <iostream>
 
8
 
 
9
using namespace std;
 
10
using namespace Arts;
 
11
 
 
12
typedef WeakReference<PortDesc> PortDesc_wref;
 
13
typedef WeakReference<ModuleDesc> ModuleDesc_wref;
 
14
typedef WeakReference<StructureDesc> StructureDesc_wref;
 
15
 
 
16
class PortDesc_impl :virtual public Arts::PortDesc_skel {
 
17
protected:
 
18
        string _name;
 
19
        PortType _type;
 
20
        vector<PortDesc_wref> _connections;
 
21
        ModuleDesc_wref _parent;
 
22
        bool _isConnected;
 
23
        bool _hasValue;
 
24
        Any      _value;
 
25
        long _ID;
 
26
        long _oldID;
 
27
        list<long> oldConnections;
 
28
 
 
29
        void removeNullConnections();
 
30
 
 
31
public:
 
32
        ~PortDesc_impl();
 
33
 
 
34
        inline PortDesc self() { return PortDesc::_from_base(_copy()); }
 
35
        void constructor(ModuleDesc parent, const string& name, const PortType& type);
 
36
 
 
37
        void disconnectAll();
 
38
        long ID();
 
39
        ModuleDesc parent();
 
40
        string name();
 
41
        PortType type();
 
42
        bool isConnected();
 
43
        bool hasValue();
 
44
        void hasValue(bool newvalue);
 
45
        vector<PortDesc> *connections();
 
46
        float floatValue();
 
47
        void floatValue( float _new_value );
 
48
 
 
49
        string stringValue();
 
50
        void stringValue( const string& _new_value );
 
51
 
 
52
        Any value();
 
53
        void value( const Any& _new_value );
 
54
 
 
55
        bool connectTo( PortDesc port );
 
56
        void internalConnectInput( PortDesc port );
 
57
        void disconnectFrom( PortDesc port );
 
58
 
 
59
        void loadFromList(const vector<string>& list);
 
60
        vector<string> *saveToList();
 
61
 
 
62
        void internalReConnect( const vector<PortDesc>& allports );
 
63
        long internalOldID();
 
64
};
 
65
 
 
66
class ModuleDesc_impl : virtual public ModuleDesc_skel {
 
67
private:
 
68
        long _ID;
 
69
        StructureDesc_wref _parent;
 
70
        string _name;
 
71
        long _x, _y;
 
72
        vector<PortDesc> _ports;
 
73
        long collectPorts( const Arts::ModuleInfo& info );
 
74
 
 
75
        bool _isInterface, _isStructure;
 
76
 
 
77
        inline ModuleDesc self() { return ModuleDesc::_from_base(_copy()); }
 
78
 
 
79
public:
 
80
        long ID();
 
81
        StructureDesc parent();
 
82
        string name();
 
83
        vector<PortDesc> *ports();
 
84
        long height();
 
85
        long width();
 
86
        long x();
 
87
        long y();
 
88
        bool moveTo( long x, long y );
 
89
        void constructor( StructureDesc parent, const ModuleInfo& info );
 
90
 
 
91
        void loadFromList(const vector<string>& list);
 
92
        vector<string> *saveToList();
 
93
 
 
94
        ~ModuleDesc_impl();
 
95
 
 
96
        bool isInterface();
 
97
        bool isStructure();
 
98
        Arts::PortDesc findPort(const string& name);
 
99
};
 
100
 
 
101
class StructureDesc_impl : virtual public Arts::StructureDesc_skel {
 
102
protected:
 
103
        bool _valid;
 
104
        vector<ModuleDesc> _modules;
 
105
        vector<StructurePortDesc> _ports;       /* only structure ports which are part of the interface */
 
106
        long nextID;
 
107
        ModuleInfo _externalInterface;
 
108
 
 
109
        inline StructureDesc self() { return StructureDesc::_from_base(_copy()); }
 
110
public:
 
111
        string name();
 
112
        void name(const string& newName);       
 
113
 
 
114
        vector<string> *saveToList();
 
115
        void loadFromList(const vector<string>& list);
 
116
        vector<ModuleDesc> *modules();
 
117
        vector<StructurePortDesc> *ports();
 
118
 
 
119
        void clear();
 
120
        long obtainID();
 
121
        long width();
 
122
        long height();
 
123
        bool valid();
 
124
 
 
125
        ModuleDesc createModuleDesc( const ModuleInfo& info );
 
126
        ModuleDesc createModuleDesc( const string& name );
 
127
        void freeModuleDesc(ModuleDesc moduledesc);
 
128
 
 
129
        // external interface
 
130
        StructurePortDesc createStructurePortDesc(const PortType& type, const string& name);
 
131
        void freeStructurePortDesc(StructurePortDesc portdesc);
 
132
        void moveStructurePortDesc(StructurePortDesc portdesc, long newposition);
 
133
 
 
134
        ModuleInfo externalInterface();
 
135
 
 
136
        StructureDesc_impl();
 
137
        ~StructureDesc_impl();
 
138
};
 
139
 
 
140
class StructurePortDesc_impl :
 
141
        virtual public PortDesc_impl,
 
142
        virtual public StructurePortDesc_skel
 
143
{
 
144
protected:
 
145
        StructureDesc_wref _parentStructure;
 
146
        long _x, _y, _position;
 
147
 
 
148
        inline StructurePortDesc self() {
 
149
                return StructurePortDesc::_from_base(_copy());
 
150
        }
 
151
public:
 
152
        void constructor(StructureDesc parent, const string& name,
 
153
                                        const PortType& type);
 
154
        ~StructurePortDesc_impl();
 
155
 
 
156
        long x();
 
157
        long y();
 
158
        long position();
 
159
        void lowerPosition();
 
160
        void raisePosition();
 
161
        void rename(const string& newname);
 
162
 
 
163
        void internalSetPosition(long position);
 
164
        StructureDesc parentStructure();
 
165
        bool moveTo( long X, long Y );
 
166
 
 
167
        void loadFromList(const vector<string>& list);
 
168
        vector<string> *saveToList();
 
169
};
 
170
 
 
171
REGISTER_IMPLEMENTATION(PortDesc_impl);
 
172
REGISTER_IMPLEMENTATION(ModuleDesc_impl);
 
173
REGISTER_IMPLEMENTATION(StructureDesc_impl);
 
174
REGISTER_IMPLEMENTATION(StructurePortDesc_impl);
 
175
 
 
176
/*
 
177
#include "structures.h"
 
178
#include "sequenceutils.h"
 
179
*/
 
180
#include "debug.h"
 
181
#include <vector>
 
182
#include <algorithm>
 
183
 
 
184
#define dname(dir) ((dir)==Arts::input?"input":"output")
 
185
#define pstat \
 
186
        printf("port name %s, direction %s, id %d\n",_Name.c_str(),dname(_Type.direction),_ID);
 
187
 
 
188
void PortDesc_impl::constructor(ModuleDesc parent, const string& name,
 
189
                                                                                                        const PortType& type)
 
190
{
 
191
#if 0
 
192
        if(parent)
 
193
        {
 
194
                char * pname = parent->Name();
 
195
                describe("PortDesc."+string(pname)+string(".")+name);
 
196
        }
 
197
        else
 
198
        {
 
199
                describe("PortDesc.Structure."+name);
 
200
        }
 
201
#endif
 
202
        _name = name;
 
203
        _type = type;
 
204
        _parent = parent;
 
205
        _isConnected = false;
 
206
        _hasValue = false;
 
207
        _value.type = _type.dataType;
 
208
 
 
209
        if(!parent.isNull())
 
210
        {
 
211
                StructureDesc sd = parent.parent();
 
212
                _ID = sd.obtainID();
 
213
        }
 
214
        // else: assume that some smart object which derives from us will set the ID accordingly
 
215
        //  -> for instance StructurePortDesc_impl does so
 
216
}
 
217
 
 
218
#if 0 /* PORT */
 
219
void PortDesc_impl::cleanUp()
 
220
{
 
221
        disconnectAll();
 
222
        delete _Connections;
 
223
}
 
224
#endif
 
225
 
 
226
/*
 
227
 * This is new and related to weak references, it purges all null references from _connections
 
228
 */
 
229
void PortDesc_impl::removeNullConnections()
 
230
{
 
231
        vector<PortDesc_wref>::iterator i = _connections.begin();
 
232
 
 
233
        while(i != _connections.end())
 
234
        {
 
235
                PortDesc pd = *i;
 
236
                if(pd.isNull())
 
237
                {
 
238
                        _connections.erase(i);
 
239
                        i = _connections.begin();
 
240
                        printf("removeNullConnections() removed something (shouldn't happen)\n");
 
241
                }
 
242
                else i++;
 
243
        }
 
244
 
 
245
        _isConnected = !_connections.empty();
 
246
}
 
247
 
 
248
void PortDesc_impl::disconnectAll()
 
249
{
 
250
        // disconnect all connected ports
 
251
        while(!_connections.empty())
 
252
        {
 
253
                PortDesc pd = _connections.front();
 
254
 
 
255
                if(pd.isNull())         // weak references can automatically disappear
 
256
                        _connections.erase(_connections.begin());
 
257
                else
 
258
                        pd.disconnectFrom(self());
 
259
        }
 
260
}
 
261
 
 
262
PortDesc_impl::~PortDesc_impl()
 
263
{
 
264
}
 
265
 
 
266
// Implementation for interface PortDesc
 
267
long PortDesc_impl::ID()
 
268
{
 
269
        return _ID; 
 
270
}
 
271
 
 
272
ModuleDesc PortDesc_impl::parent()
 
273
{
 
274
        return _parent; 
 
275
}
 
276
 
 
277
string PortDesc_impl::name()
 
278
{
 
279
        return _name;
 
280
}
 
281
 
 
282
PortType PortDesc_impl::type()
 
283
{
 
284
        return _type; 
 
285
}
 
286
 
 
287
bool PortDesc_impl::isConnected()
 
288
{
 
289
        if(_isConnected) removeNullConnections();
 
290
        return _isConnected; 
 
291
}
 
292
 
 
293
bool PortDesc_impl::hasValue()
 
294
{
 
295
        return _hasValue; 
 
296
}
 
297
 
 
298
void PortDesc_impl::hasValue(bool newvalue)
 
299
{
 
300
        if(_hasValue != newvalue)
 
301
        {
 
302
                assert(newvalue == false);
 
303
                _hasValue = newvalue;
 
304
        }
 
305
}
 
306
 
 
307
vector<PortDesc> *PortDesc_impl::connections()
 
308
{
 
309
        vector<PortDesc_wref>::iterator i;
 
310
        vector<PortDesc> *result = new vector<PortDesc>;
 
311
 
 
312
        for(i = _connections.begin(); i != _connections.end(); i++)
 
313
        {
 
314
                PortDesc pd = *i;
 
315
                if(!pd.isNull()) result->push_back(pd);
 
316
        }
 
317
        return result; 
 
318
}
 
319
 
 
320
float PortDesc_impl::floatValue()
 
321
{
 
322
        assert(_hasValue);
 
323
        assert(_type.dataType == "float");
 
324
 
 
325
        Buffer b;
 
326
        b.write(_value.value);
 
327
        return b.readFloat();
 
328
}
 
329
 
 
330
void PortDesc_impl::floatValue( float _new_value )
 
331
{
 
332
        assert(!_isConnected);
 
333
        assert(_type.direction == Arts::input);
 
334
        assert(_type.dataType == "float");
 
335
        assert(_value.type == "float");
 
336
 
 
337
        Buffer b;
 
338
        b.writeFloat(_new_value);
 
339
        b.read(_value.value, b.size());
 
340
        _hasValue = true;
 
341
}
 
342
 
 
343
string PortDesc_impl::stringValue()
 
344
{
 
345
        assert(_hasValue);
 
346
        assert(_type.dataType == "string");
 
347
        assert(_value.type == "string");
 
348
 
 
349
        string result;
 
350
        Buffer b;
 
351
        b.write(_value.value);
 
352
        b.readString(result);
 
353
        return result;
 
354
}
 
355
 
 
356
void PortDesc_impl::stringValue( const string& _new_value )
 
357
{
 
358
        assert(!_isConnected);  // shouldn't happen, but check anyway
 
359
        assert(_type.direction == Arts::input);
 
360
        assert(_type.dataType == "string");
 
361
 
 
362
        Buffer b;
 
363
        b.writeString(_new_value);
 
364
        b.read(_value.value, b.size());
 
365
        _hasValue = true;
 
366
}
 
367
 
 
368
Any PortDesc_impl::value()
 
369
{
 
370
        assert(_hasValue);
 
371
        return _value;
 
372
}
 
373
 
 
374
void PortDesc_impl::value( const Any& _new_value )
 
375
{
 
376
        _value = _new_value;
 
377
        _hasValue = true;
 
378
}
 
379
 
 
380
bool PortDesc_impl::connectTo( PortDesc port )
 
381
{
 
382
        removeNullConnections();
 
383
 
 
384
        // check if we are already connected to that port:
 
385
 
 
386
        unsigned long i;
 
387
        for(i=0;i<_connections.size();i++)
 
388
        {
 
389
                PortDesc pd = _connections[i];
 
390
                if(pd.ID() == port.ID()) return true;
 
391
        }
 
392
 
 
393
        const PortType& rType = port.type();
 
394
 
 
395
        // only stream or event channels may be connected
 
396
        if( _type.connType != rType.connType )
 
397
                return false;
 
398
 
 
399
        // TODO: eventually check conditions when it is legal to connect property
 
400
        // ports, and when it is insane (_Type.connType == Arts::property)
 
401
        //
 
402
        // for incoming structure ports, for instance, it is perfectly allright
 
403
 
 
404
        // only same data type connections allowed
 
405
        if( _type.dataType != rType.dataType )
 
406
                return false;
 
407
 
 
408
        // only opposite directions
 
409
        if( _type.direction == rType.direction )
 
410
                return false;
 
411
 
 
412
        // always first connect the input port to the output port and
 
413
        // then the other direction
 
414
 
 
415
        if( _type.direction == Arts::input )
 
416
        {
 
417
                if(!_isConnected || _type.isMultiPort)
 
418
                {
 
419
                        assert(_connections.empty() || _type.isMultiPort);
 
420
                        _connections.push_back(port);
 
421
 
 
422
                        port.internalConnectInput(self());
 
423
 
 
424
                        _isConnected = true;
 
425
                        _hasValue = false;
 
426
                        return true;
 
427
                }
 
428
        }
 
429
        if( _type.direction == Arts::output )
 
430
                return port.connectTo(self());
 
431
 
 
432
        return false;
 
433
}
 
434
 
 
435
void PortDesc_impl::internalConnectInput( PortDesc port )
 
436
{
 
437
        _connections.push_back(port);
 
438
        _isConnected = true;
 
439
}
 
440
 
 
441
void PortDesc_impl::disconnectFrom( PortDesc port )
 
442
{
 
443
        removeNullConnections();
 
444
 
 
445
        unsigned long found = 0;
 
446
 
 
447
        artsdebug("port %ld disconnecting from port %ld\n",ID(),port.ID());
 
448
 
 
449
        vector<PortDesc_wref>::iterator i = _connections.begin();
 
450
        while(!found && i != _connections.end())
 
451
        {
 
452
                Arts::PortDesc other = *i;
 
453
                if(!other.isNull() && other.ID() == port.ID())
 
454
                {
 
455
                        _connections.erase(i);
 
456
                        i = _connections.begin();
 
457
                        found++;
 
458
                }
 
459
                else i++;
 
460
        }
 
461
 
 
462
        _isConnected = !_connections.empty();
 
463
 
 
464
        ModuleDesc parent = _parent;
 
465
        if(parent.isNull())
 
466
                artsdebug("_Parent = <some structure>, isConnected = %d\n",_isConnected);
 
467
        else
 
468
                artsdebug("_Parent = %s, isConnected = %d\n",parent.name().c_str(),_isConnected);
 
469
 
 
470
        if(found)
 
471
                port.disconnectFrom(self());
 
472
}
 
473
 
 
474
// Implementation for interface ModuleDesc
 
475
long ModuleDesc_impl::ID()
 
476
{
 
477
        return _ID; 
 
478
}
 
479
 
 
480
StructureDesc ModuleDesc_impl::parent()
 
481
{
 
482
        return _parent; 
 
483
}
 
484
 
 
485
string ModuleDesc_impl::name()
 
486
{
 
487
        return _name;
 
488
}
 
489
 
 
490
vector<PortDesc> *ModuleDesc_impl::ports()
 
491
{
 
492
        return new vector<PortDesc>(_ports);
 
493
}
 
494
 
 
495
long ModuleDesc_impl::x()
 
496
{
 
497
        return _x;
 
498
}
 
499
 
 
500
long ModuleDesc_impl::y()
 
501
{
 
502
        return _y;
 
503
}
 
504
 
 
505
long ModuleDesc_impl::width()
 
506
{
 
507
        assert(false);
 
508
        return 0; 
 
509
}
 
510
 
 
511
long ModuleDesc_impl::height()
 
512
{
 
513
        assert(false);
 
514
        return 0; 
 
515
}
 
516
 
 
517
 
 
518
bool ModuleDesc_impl::moveTo( long x, long y )
 
519
{
 
520
        // FIXME: collision checking!
 
521
        _x = x;
 
522
        _y = y;
 
523
 
 
524
        return(true);
 
525
}
 
526
 
 
527
 
 
528
// Implementation for interface StructureDesc
 
529
long StructureDesc_impl::width()
 
530
{
 
531
        assert(false);
 
532
        return 0; 
 
533
}
 
534
 
 
535
long StructureDesc_impl::height()
 
536
{
 
537
        assert(false);
 
538
        return 0; 
 
539
}
 
540
 
 
541
/*
 
542
 * Query the module for it's paramenters
 
543
 */
 
544
 
 
545
void ModuleDesc_impl::constructor( StructureDesc parent,
 
546
                                                                const Arts::ModuleInfo& info )
 
547
{
 
548
        _name = info.name;
 
549
        _x = -1;                // no position assigned
 
550
        _y = -1;
 
551
        _ID = parent.obtainID();
 
552
        _parent = parent;
 
553
        _isInterface = info.isInterface;
 
554
        _isStructure = info.isStructure;
 
555
 
 
556
        collectPorts(info);
 
557
}
 
558
 
 
559
ModuleDesc_impl::~ModuleDesc_impl()
 
560
{
 
561
}
 
562
 
 
563
bool ModuleDesc_impl::isInterface()
 
564
{
 
565
        return _isInterface;
 
566
}
 
567
 
 
568
bool ModuleDesc_impl::isStructure()
 
569
{
 
570
        return _isStructure;
 
571
}
 
572
 
 
573
 
 
574
PortDesc ModuleDesc_impl::findPort(const string& name)
 
575
{
 
576
        vector<PortDesc>::iterator p;
 
577
 
 
578
        for(p = _ports.begin(); p != _ports.end(); p++)
 
579
        {
 
580
                if(name == p->name()) return *p;
 
581
        }
 
582
 
 
583
        return PortDesc::null();
 
584
}
 
585
 
 
586
long ModuleDesc_impl::collectPorts( const Arts::ModuleInfo& info )
 
587
{
 
588
        vector<PortType>::const_iterator i;
 
589
        vector<string>::const_iterator ni = info.portnames.begin();
 
590
        long portcount = 0;
 
591
 
 
592
        for(i=info.ports.begin(); i != info.ports.end(); i++)
 
593
        {
 
594
                const PortType& porttype = *i;
 
595
                const string& portname = *ni++;
 
596
 
 
597
                artsdebug("#%d: %s\n",portcount,portname.c_str());
 
598
 
 
599
                PortDesc pd(self(),portname,porttype);
 
600
                _ports.push_back(pd);
 
601
                portcount++;
 
602
        }
 
603
        return(portcount);
 
604
}
 
605
 
 
606
ModuleDesc StructureDesc_impl::createModuleDesc( const ModuleInfo& info )
 
607
{
 
608
        Arts::ModuleDesc result = createModuleDesc(info.name);
 
609
 
 
610
        assert(!result.isNull());
 
611
        return result;
 
612
}
 
613
 
 
614
ModuleDesc StructureDesc_impl::createModuleDesc( const string& name )
 
615
{
 
616
        /* FIXME: need new comment
 
617
         * to create a representation of a specified synth module, we
 
618
         *
 
619
         * - create an instance of this synth module by contacting the
 
620
         *   module server and telling him to do so (result is a C++ class)
 
621
         *
 
622
         * - create an instance of a ModuleDesc, and tell it to query the
 
623
         *   module for it's parameters (result is a CORBA object)
 
624
         *
 
625
         * - destroy the synth module (C++ class) again and return a reference
 
626
         *   to the CORBA object
 
627
         */
 
628
/*
 
629
        ModuleServer<SynthModule> *MS_SynthModule;
 
630
        MS_SynthModule = (ModuleServer<SynthModule> *)SynthModule::get_MS();
 
631
 
 
632
        SynthModule *m = (SynthModule *)MS_SynthModule->getModule(name);
 
633
*/
 
634
#if 0
 
635
        Arts::ModuleInfo_var info = ModuleBroker->lookupModule(name);
 
636
        if(!info) return 0;
 
637
#endif
 
638
        const Arts::ModuleInfo& info = makeModuleInfo(name);
 
639
        Arts::ModuleDesc moduledesc = ModuleDesc(self(),info);
 
640
        _modules.push_back(moduledesc);
 
641
        return moduledesc;
 
642
}
 
643
 
 
644
void StructureDesc_impl::freeModuleDesc(ModuleDesc moduledesc)
 
645
{
 
646
        vector<ModuleDesc>::iterator i;
 
647
 
 
648
        for(i=_modules.begin();i != _modules.end(); i++)
 
649
        {
 
650
                Arts::ModuleDesc current = *i;
 
651
 
 
652
                if(current.ID() == moduledesc.ID())
 
653
                {
 
654
                        _modules.erase(i);              // will get freed automagically
 
655
                        return;
 
656
                }
 
657
        }
 
658
}
 
659
 
 
660
vector<ModuleDesc> *StructureDesc_impl::modules()
 
661
{
 
662
        vector<ModuleDesc> *retval = new vector<ModuleDesc>(_modules);
 
663
        return(retval);
 
664
}
 
665
 
 
666
StructureDesc_impl::StructureDesc_impl()
 
667
{
 
668
        arts_debug("PORT: created structuredesc_impl");
 
669
        nextID = 0;
 
670
        _valid = true;
 
671
        _externalInterface.name = "unknown";            // FIXME
 
672
        _externalInterface.isStructure = true;
 
673
        _externalInterface.isInterface = false;
 
674
}
 
675
 
 
676
StructureDesc_impl::~StructureDesc_impl()
 
677
{
 
678
        artsdebug("StructureDesc released...\n");
 
679
}
 
680
 
 
681
long StructureDesc_impl::obtainID()
 
682
{
 
683
        return(nextID++);
 
684
}
 
685
 
 
686
bool StructureDesc_impl::valid()
 
687
{
 
688
        return(_valid);
 
689
}
 
690
 
 
691
void StructureDesc_impl::clear()
 
692
{
 
693
        _modules.clear();
 
694
        _ports.clear();
 
695
        _valid = true;
 
696
}
 
697
 
 
698
// "file" management
 
699
 
 
700
vector<string> *PortDesc_impl::saveToList()
 
701
{
 
702
        vector<string> *list = new vector<string>;
 
703
 
 
704
        sqprintf(list,"id=%ld",_ID);
 
705
        if(_hasValue)
 
706
        {
 
707
                if(_type.dataType == "string")
 
708
                {
 
709
                        sqprintf(list,"string_data=%s",stringValue().c_str());
 
710
                }
 
711
                else if(_type.dataType == "float")
 
712
                {
 
713
                        sqprintf(list,"audio_data=%2.5f",floatValue());
 
714
                }
 
715
                else
 
716
                {
 
717
                        Buffer b;
 
718
                        _value.writeType(b);
 
719
                        sqprintf(list,"any_data=%s",b.toString("value").c_str());
 
720
                }
 
721
        }
 
722
 
 
723
        if(_isConnected)
 
724
        {
 
725
                vector<PortDesc_wref>::iterator i;
 
726
 
 
727
                for(i=_connections.begin();i != _connections.end(); i++)
 
728
                {
 
729
                        Arts::PortDesc port = *i;
 
730
                        if(!port.isNull()) sqprintf(list,"connect_to=%ld",port.ID());
 
731
                }
 
732
        }
 
733
        return list;
 
734
}
 
735
 
 
736
vector<string> *ModuleDesc_impl::saveToList()
 
737
{
 
738
        vector<string> *list = new vector<string>;
 
739
        vector<PortDesc>::iterator i;
 
740
 
 
741
        sqprintf(list,"id=%ld",_ID);
 
742
        sqprintf(list,"x=%ld",_x);
 
743
        sqprintf(list,"y=%ld",_y);
 
744
        for(i=_ports.begin();i != _ports.end();i++)
 
745
        {
 
746
                PortDesc pd = *i;
 
747
                sqprintf(list,"port=%s",pd.name().c_str());
 
748
 
 
749
                vector<string> *portlist = pd.saveToList();
 
750
                addSubStringSeq(list,portlist);
 
751
                delete portlist;
 
752
        }
 
753
        return list;
 
754
}
 
755
 
 
756
vector<string> *StructureDesc_impl::saveToList()
 
757
{
 
758
        vector<string> *list = new vector<string>;
 
759
        vector<ModuleDesc>::iterator mi;
 
760
        vector<StructurePortDesc>::iterator pi;
 
761
 
 
762
        sqprintf(list,"name=%s",_externalInterface.name.c_str());
 
763
        for(mi=_modules.begin();mi != _modules.end();mi++)
 
764
        {
 
765
                ModuleDesc md = *mi;
 
766
                sqprintf(list,"module=%s",md.name().c_str());
 
767
 
 
768
                vector<string> *modulelist = md.saveToList();
 
769
                addSubStringSeq(list,modulelist);
 
770
                delete modulelist;
 
771
        }
 
772
        for(pi=_ports.begin(); pi!=_ports.end(); pi++)
 
773
        {
 
774
                Arts::StructurePortDesc spd = *pi;
 
775
                sqprintf(list,"structureport");
 
776
 
 
777
                vector<string> *portlist= spd.saveToList();
 
778
                addSubStringSeq(list,portlist);
 
779
                delete portlist;
 
780
        }
 
781
        return list;
 
782
}
 
783
 
 
784
void PortDesc_impl::internalReConnect( const vector<PortDesc>& allports )
 
785
{
 
786
        vector<PortDesc>::const_iterator i;
 
787
 
 
788
        for(i=allports.begin(); i != allports.end(); i++)
 
789
        {
 
790
                PortDesc pd = (*i);
 
791
                long oid = pd.internalOldID();
 
792
 
 
793
                if(find(oldConnections.begin(),oldConnections.end(),oid)
 
794
                                                                                                        != oldConnections.end())
 
795
                {
 
796
                        connectTo(pd);
 
797
                }
 
798
        }
 
799
}
 
800
 
 
801
long PortDesc_impl::internalOldID()
 
802
{
 
803
        return _oldID;
 
804
}
 
805
 
 
806
void PortDesc_impl::loadFromList(const vector<string>& list)
 
807
{
 
808
        unsigned long i;
 
809
        string cmd,param;
 
810
        for(i=0;i<list.size();i++)
 
811
        {
 
812
                if(parse_line(list[i],cmd,param))       // otherwise: empty or comment
 
813
                {
 
814
                        if(cmd == "audio_data") {
 
815
                                floatValue(atof(param.c_str()));
 
816
                        } else if(cmd == "string_data") {
 
817
                                stringValue(param);
 
818
                        } else if(cmd == "any_data") {
 
819
                                Buffer b;
 
820
                                if(b.fromString(param,"value"))
 
821
                                {
 
822
                                        Any any;
 
823
                                        any.readType(b);
 
824
                                        if(!b.readError() && !b.remaining())
 
825
                                                value(any);
 
826
                                }
 
827
                        } else if(cmd == "id") {
 
828
                                _oldID = atol(param.c_str());
 
829
                        } else if(cmd == "connect_to") {
 
830
                                oldConnections.push_back(atol(param.c_str()));
 
831
                        }
 
832
                }
 
833
        }
 
834
}
 
835
 
 
836
void ModuleDesc_impl::loadFromList(const vector<string>& list)
 
837
{
 
838
        artsdebug("mlist-----------\n");
 
839
        unsigned long i;
 
840
        string cmd, param;
 
841
        for(i=0;i<list.size();i++)
 
842
        {
 
843
                if(parse_line(list[i],cmd,param))       // otherwise: empty or comment
 
844
                {
 
845
                        artsdebug("MD: load-> cmd was %s\n",cmd.c_str());
 
846
                        if(cmd == "port")
 
847
                        {
 
848
                                string portName =
 
849
                                        OldFormatTranslator::newPortName(_name,param);
 
850
                                PortDesc pd = PortDesc::null();
 
851
                                vector<PortDesc>::iterator pi;
 
852
 
 
853
                                for(pi=_ports.begin(); pi != _ports.end(); pi++)
 
854
                                {
 
855
                                        artsdebug("pdi = %s, portName = %s\n",pi->name().c_str(),
 
856
                                                                           portName.c_str());
 
857
                                        if(pi->name() == portName) pd = *pi;
 
858
                                }
 
859
                                assert(!pd.isNull());
 
860
 
 
861
                                vector<string> *plist = getSubStringSeq(&list,i);
 
862
                                pd.loadFromList(*plist);
 
863
                                delete plist;
 
864
                        } else if(cmd == "x") {
 
865
                                _x = atol(param.c_str());
 
866
                                artsdebug("X set to %ld (param was %s)\n",_x,param.c_str());
 
867
                        } else if(cmd == "y") {
 
868
                                _y = atol(param.c_str());
 
869
                                artsdebug("Y set to %ld (param was %s)\n",_y,param.c_str());
 
870
                        }
 
871
                }
 
872
        }
 
873
        artsdebug("-----------mlist\n");
 
874
}
 
875
 
 
876
void StructureDesc_impl::loadFromList(const vector<string>& list)
 
877
{
 
878
        string cmd,param;
 
879
        unsigned long i;
 
880
        vector<PortDesc> allports;
 
881
 
 
882
        clear();
 
883
        _externalInterface.name = (const char *)"unknown";
 
884
 
 
885
        artsdebug("loadFromList; listlen = %ld\n",list.size());
 
886
        for(i=0;i<list.size();i++)
 
887
        {
 
888
                if(parse_line(list[i],cmd,param))       // otherwise: empty or comment
 
889
                {
 
890
                        artsdebug("SD: load-> cmd was %s\n",cmd.c_str());
 
891
                        if(cmd == "module")
 
892
                        {
 
893
                                string newName = OldFormatTranslator::newModuleName(param);
 
894
                                ModuleDesc md = createModuleDesc(newName);
 
895
 
 
896
                                vector<string> *mlist = getSubStringSeq(&list,i);
 
897
 
 
898
                                if(!md.isNull())
 
899
                                {
 
900
                                        md.loadFromList(*mlist);
 
901
 
 
902
                                        // PORT: order changed
 
903
                                        vector<PortDesc> *pd = md.ports();
 
904
                                        vector<PortDesc>::iterator pi;
 
905
                                        for(pi = pd->begin(); pi != pd->end();pi++) 
 
906
                                                allports.push_back(*pi);
 
907
 
 
908
                                        delete pd;
 
909
                                }
 
910
                                else
 
911
                                {
 
912
                                        // module couldn't be found
 
913
                                        _valid = false;
 
914
                                }
 
915
                                delete mlist;
 
916
                        }
 
917
                        else if(cmd == "name")
 
918
                        {
 
919
                                _externalInterface.name = param;
 
920
                        }
 
921
                        else if(cmd == "structureport")
 
922
                        {
 
923
                                // just to have valid values to pass to the new (to be loaded)
 
924
                                // port:
 
925
                                PortType type;
 
926
                                type.direction = Arts::input;
 
927
                                type.dataType = "float";
 
928
                                type.connType = Arts::conn_stream;
 
929
 
 
930
                                StructurePortDesc spd =
 
931
                                        createStructurePortDesc(type,"unknown");
 
932
 
 
933
                                vector<string> *splist = getSubStringSeq(&list,i);
 
934
                                spd.loadFromList(*splist);
 
935
                                delete splist;
 
936
 
 
937
                                // yes; this is a port as well
 
938
                                allports.push_back(spd);
 
939
                        }
 
940
                }
 
941
        }
 
942
 
 
943
        for(i=0;i<allports.size();i++)
 
944
                allports[i].internalReConnect(allports);
 
945
}
 
946
 
 
947
void StructureDesc_impl::name(const string& name)
 
948
{
 
949
        _externalInterface.name = name;
 
950
}
 
951
 
 
952
string StructureDesc_impl::name()
 
953
{
 
954
        return _externalInterface.name;
 
955
}
 
956
 
 
957
long extint_pscore(StructurePortDesc p)
 
958
{
 
959
        long result = p.position(); //p->X()*1000+p->Y();
 
960
        if(p.type().direction == Arts::input) result += 5000000;
 
961
 
 
962
        return result;
 
963
}
 
964
 
 
965
bool extint_port_compare(StructurePortDesc p1, StructurePortDesc p2)
 
966
{
 
967
        long p1s = extint_pscore(p1);
 
968
        long p2s = extint_pscore(p2);
 
969
 
 
970
        artsdebug("compare; [%s] = %d  ;  [%s] = %d\n", p1.name().c_str(),p1s,
 
971
                                                                                                        p2.name().c_str(),p2s);
 
972
        return (p1s < p2s);
 
973
// return -1;
 
974
        //if(p1s == p2s) return 0;
 
975
        //return 1;
 
976
}
 
977
 
 
978
ModuleInfo StructureDesc_impl::externalInterface()
 
979
{
 
980
        ModuleInfo result = _externalInterface;
 
981
        vector<StructurePortDesc> sorted_ports = _ports;
 
982
        vector<StructurePortDesc>::iterator p;
 
983
        unsigned long l;
 
984
/* PORT:
 
985
        for(l=0;l<_Ports->length();l++) sorted_ports.push_back((*_Ports)[l]);
 
986
*/
 
987
        sort(sorted_ports.begin(),sorted_ports.end(),extint_port_compare);
 
988
 
 
989
        l = 0;
 
990
        for(p=sorted_ports.begin();p != sorted_ports.end();p++)
 
991
        {
 
992
                string pname = p->name();
 
993
                PortType ptype = p->type();
 
994
 
 
995
                if(ptype.direction == Arts::input)
 
996
                        ptype.direction = Arts::output;
 
997
                else
 
998
                        ptype.direction = Arts::input;
 
999
 
 
1000
                artsdebug("externalInterface; sorted ports: %d => %s\n",l,pname.c_str());
 
1001
                result.ports.push_back(ptype);
 
1002
                result.portnames.push_back(pname);
 
1003
                l++;
 
1004
        }
 
1005
        return result;
 
1006
}
 
1007
 
 
1008
vector<StructurePortDesc> *StructureDesc_impl::ports()
 
1009
{
 
1010
        return new vector<StructurePortDesc>(_ports);
 
1011
}
 
1012
 
 
1013
StructurePortDesc StructureDesc_impl::createStructurePortDesc(
 
1014
                const Arts::PortType& type, const string& name)
 
1015
{
 
1016
        artsdebug("creating new port %s\n",name.c_str());
 
1017
        StructurePortDesc port(self(), name, type);
 
1018
        _ports.push_back(port);
 
1019
 
 
1020
        // set the Position (put it at the end of the ports)
 
1021
        unsigned long i, count = 0;
 
1022
        for(i=0;i<_ports.size();i++)
 
1023
        {
 
1024
                if(_ports[i].type().direction == type.direction) count++;
 
1025
        }
 
1026
        assert(count > 0);      // we just inserted one ;)
 
1027
        port.internalSetPosition(count-1);
 
1028
        return port;
 
1029
}
 
1030
 
 
1031
void StructureDesc_impl::freeStructurePortDesc(StructurePortDesc portdesc)
 
1032
{
 
1033
        vector<StructurePortDesc>::iterator i;
 
1034
 
 
1035
        for(i=_ports.begin(); i != _ports.end(); i++)
 
1036
        {
 
1037
                if(i->ID() == portdesc.ID())
 
1038
                {
 
1039
                        _ports.erase(i);
 
1040
                        return;
 
1041
                }
 
1042
        }
 
1043
}
 
1044
 
 
1045
void StructureDesc_impl::moveStructurePortDesc(StructurePortDesc
 
1046
                                                                                        portdesc, long newposition)
 
1047
{
 
1048
        const Arts::PortType& type = portdesc.type();
 
1049
 
 
1050
        unsigned long i;
 
1051
        long count = 0;
 
1052
        for(i=0;i<_ports.size();i++)
 
1053
        {
 
1054
                if(_ports[i].type().direction == type.direction) count++;
 
1055
        }
 
1056
 
 
1057
        if(newposition < 0) newposition = 0;
 
1058
        if(newposition > count-1) newposition = count-1;
 
1059
 
 
1060
        if(newposition == portdesc.position()) return;
 
1061
 
 
1062
        int delta, lower, upper;
 
1063
 
 
1064
        if(newposition > portdesc.position())
 
1065
        {
 
1066
                // if the port gets a higher position, move all ports that
 
1067
                // are between it's current position and its new position down one
 
1068
                lower = portdesc.position();
 
1069
                upper = newposition;
 
1070
                delta = -1;
 
1071
        }
 
1072
        else
 
1073
        {
 
1074
                // if the port gets a lower position, move all ports that
 
1075
                // are between it's current position and its new position up one
 
1076
                lower = newposition;
 
1077
                upper = portdesc.position();
 
1078
                delta = 1;
 
1079
        }
 
1080
 
 
1081
        for(i=0;i<_ports.size();i++)
 
1082
        {
 
1083
                StructurePortDesc pd  = _ports[i];
 
1084
                
 
1085
                if(pd.type().direction == type.direction)
 
1086
                {
 
1087
                        if(pd.ID() != portdesc.ID() &&
 
1088
                                pd.position() >= lower && pd.position() <= upper)
 
1089
                        {
 
1090
                                pd.internalSetPosition(pd.position()+delta);
 
1091
                        }
 
1092
                }
 
1093
 
 
1094
        }
 
1095
        portdesc.internalSetPosition(newposition);
 
1096
}
 
1097
 
 
1098
void StructurePortDesc_impl::constructor(StructureDesc parent,
 
1099
                                                                const string& name, const PortType& type)
 
1100
{
 
1101
        PortDesc_impl::constructor(ModuleDesc::null(),name,type);
 
1102
        _parentStructure = parent;
 
1103
        _ID = parent.obtainID();
 
1104
        _x = 0;
 
1105
        _y = 0;
 
1106
        _position = 0;
 
1107
}
 
1108
 
 
1109
StructurePortDesc_impl::~StructurePortDesc_impl()
 
1110
{
 
1111
        // this destructor is required to make some compilers (egcs-1.1.2) compile
 
1112
}
 
1113
 
 
1114
long StructurePortDesc_impl::x()
 
1115
{       
 
1116
        return _x;
 
1117
}
 
1118
 
 
1119
long StructurePortDesc_impl::y()
 
1120
{
 
1121
        return _y;
 
1122
}
 
1123
 
 
1124
long StructurePortDesc_impl::position()
 
1125
{
 
1126
        return _position;
 
1127
}
 
1128
 
 
1129
void StructurePortDesc_impl::lowerPosition()
 
1130
{
 
1131
        StructureDesc parent = _parentStructure;                // weak reference
 
1132
 
 
1133
        if(!parent.isNull())
 
1134
                parent.moveStructurePortDesc(self(), _position-1);
 
1135
}
 
1136
 
 
1137
void StructurePortDesc_impl::raisePosition()
 
1138
{
 
1139
        StructureDesc parent = _parentStructure;                // weak reference
 
1140
 
 
1141
        if(!parent.isNull())
 
1142
                parent.moveStructurePortDesc(self(), _position+1);
 
1143
}
 
1144
 
 
1145
void StructurePortDesc_impl::rename(const string& newname)
 
1146
{
 
1147
        _name = newname;
 
1148
}
 
1149
 
 
1150
// only used by the structure to reorder the ports
 
1151
void StructurePortDesc_impl::internalSetPosition(long position)
 
1152
{
 
1153
        _position = position;
 
1154
}
 
1155
 
 
1156
StructureDesc StructurePortDesc_impl::parentStructure()
 
1157
{
 
1158
        return _parentStructure;
 
1159
}
 
1160
 
 
1161
bool StructurePortDesc_impl::moveTo( long X, long Y )
 
1162
{
 
1163
        // FIXME: check space
 
1164
        _x = X;
 
1165
        _y = Y;
 
1166
 
 
1167
        return true;
 
1168
}
 
1169
 
 
1170
/*
 
1171
  override load & save behaviour this kind of port requires that we save the type
 
1172
  of the port as well, that means all of the porttype:
 
1173
 
 
1174
        enum PortDirection {input, output};
 
1175
        enum PortDataType {audio_data, string_data};
 
1176
        enum PortConnType {stream, event, property};
 
1177
        struct PortType {
 
1178
                PortDirection direction;
 
1179
                PortDataType dataType;
 
1180
                PortConnType connType;
 
1181
        };
 
1182
 
 
1183
  so when saved, it will look like that: 
 
1184
 
 
1185
        {
 
1186
      name=fasel
 
1187
      x=4
 
1188
      y=2
 
1189
          type
 
1190
          {
 
1191
            direction=input/output
 
1192
            datatype=audio/string
 
1193
            conntype=stream/event/property
 
1194
          }
 
1195
          data
 
1196
      {
 
1197
            [original port saves here]
 
1198
          }
 
1199
        }
 
1200
*/
 
1201
 
 
1202
PortType loadTypeFromList(const vector<string>& list)
 
1203
{
 
1204
        unsigned long i,loadstate = 0;
 
1205
        string cmd,param;
 
1206
        Arts::PortType result;
 
1207
 
 
1208
        for(i=0;i<list.size();i++)
 
1209
        {
 
1210
                if(parse_line(list[i],cmd,param))       // otherwise: empty or comment
 
1211
                {
 
1212
                        artsdebug("PortType: load-> cmd was %s\n",cmd.c_str());
 
1213
                        if(cmd == "direction")
 
1214
                        {
 
1215
                                if(param == "input") {
 
1216
                                        result.direction = Arts::input;
 
1217
                                }
 
1218
                                else if(param == "output") {
 
1219
                                        result.direction = Arts::output;
 
1220
                                }
 
1221
                                else assert(false);
 
1222
 
 
1223
                                loadstate += 1;
 
1224
                        } else if(cmd == "datatype") {
 
1225
                                if(param == "audio") {
 
1226
                                        result.dataType = "float";
 
1227
                                }
 
1228
                                else if(param == "string") {
 
1229
                                        result.dataType = "string";
 
1230
                                }
 
1231
                                else assert(false);
 
1232
 
 
1233
                                loadstate += 100;
 
1234
                        } else if(cmd == "conntype") {
 
1235
                                if(param == "stream") {
 
1236
                                        result.connType = Arts::conn_stream;
 
1237
                                }
 
1238
                                else if(param == "event") {
 
1239
                                        result.connType = Arts::conn_event;
 
1240
                                }
 
1241
                                else if(param == "property") {
 
1242
                                        result.connType = Arts::conn_property;
 
1243
                                        artsdebug("got property stuff\n");
 
1244
                                }
 
1245
                                else assert(false);
 
1246
 
 
1247
                                loadstate += 10000;
 
1248
                        }
 
1249
                }
 
1250
        }
 
1251
        assert(loadstate == 10101); // should see every member exactly once
 
1252
        return result;
 
1253
}
 
1254
 
 
1255
void StructurePortDesc_impl::loadFromList(const vector<string>& list)
 
1256
{
 
1257
        artsdebug("structureportlist-----------\n");
 
1258
        unsigned long i;
 
1259
        string cmd,param;
 
1260
        vector<string> *typelist = 0, *datalist = 0;
 
1261
        bool haveType = false, haveData = false;
 
1262
                // need both to do restore, type first
 
1263
 
 
1264
        for(i=0;i<list.size();i++)
 
1265
        {
 
1266
                if(parse_line(list[i],cmd,param))       // otherwise: empty or comment
 
1267
                {
 
1268
                        artsdebug("StructurePortDesc: load-> cmd was %s\n",cmd.c_str());
 
1269
                        if(cmd == "type")
 
1270
                        {
 
1271
                                assert(!haveType);      // only allowed once
 
1272
                                haveType = true;
 
1273
                                typelist = getSubStringSeq(&list,i);
 
1274
                        } else if(cmd == "data") {
 
1275
                                assert(!haveData);      // only allowed once
 
1276
                                haveData = true;
 
1277
                                datalist = getSubStringSeq(&list,i);
 
1278
                        } else if(cmd == "x") {
 
1279
                                _x = atol(param.c_str());
 
1280
                                artsdebug("X set to %ld (param was %s)\n",_x,param.c_str());
 
1281
                        } else if(cmd == "y") {
 
1282
                                _y = atol(param.c_str());
 
1283
                                artsdebug("Y set to %ld (param was %s)\n",_y,param.c_str());
 
1284
                        } else if(cmd == "position") {
 
1285
                                _position = atol(param.c_str());
 
1286
                                artsdebug("Position set to %ld (param was %s)\n",_position,
 
1287
                                                param.c_str());
 
1288
                        } else if(cmd == "name") {
 
1289
                                _name = param;
 
1290
                                artsdebug("Name set to %s\n",_name.c_str());
 
1291
                        }
 
1292
                }
 
1293
        }
 
1294
        assert(haveType && haveData);
 
1295
 
 
1296
        _type = loadTypeFromList(*typelist);
 
1297
 
 
1298
        if(_type.connType == Arts::conn_property) artsdebug("have property here\n");
 
1299
        PortDesc_impl::loadFromList(*datalist); 
 
1300
 
 
1301
        delete typelist;
 
1302
        delete datalist;
 
1303
        artsdebug("-----------structureportlist\n");
 
1304
}
 
1305
 
 
1306
vector<string> *saveTypeToList(const PortType& type)
 
1307
{
 
1308
        vector<string> *list = new vector<string>;
 
1309
 
 
1310
        switch(type.direction)
 
1311
        {
 
1312
                case Arts::input: sqprintf(list,"direction=input");
 
1313
                                        break;
 
1314
                case Arts::output: sqprintf(list,"direction=output");
 
1315
                                        break;
 
1316
                default: assert(false);         // should never happen!
 
1317
        }
 
1318
        if(type.dataType == "float")
 
1319
        {
 
1320
                sqprintf(list,"datatype=audio");
 
1321
        }
 
1322
        else if(type.dataType == "string")
 
1323
        {
 
1324
                sqprintf(list,"datatype=string");
 
1325
        }
 
1326
        else
 
1327
        {
 
1328
                assert(false);                          // should never happen!
 
1329
        }
 
1330
        switch(type.connType)
 
1331
        {
 
1332
                case Arts::conn_stream: sqprintf(list,"conntype=stream");
 
1333
                                        break;
 
1334
                case Arts::conn_event: sqprintf(list,"conntype=event");
 
1335
                                        break;
 
1336
                case Arts::conn_property: sqprintf(list,"conntype=property");
 
1337
                                        break;
 
1338
                default: assert(false);         // should never happen!
 
1339
        }
 
1340
        
 
1341
        return list;
 
1342
}
 
1343
 
 
1344
vector<string> *StructurePortDesc_impl::saveToList()
 
1345
{
 
1346
        vector<string> *list = new vector<string>;
 
1347
        sqprintf(list,"name=%s",_name.c_str());
 
1348
        sqprintf(list,"x=%ld",_x);
 
1349
        sqprintf(list,"y=%ld",_y);
 
1350
        sqprintf(list,"position=%ld",_position);
 
1351
        sqprintf(list,"type");
 
1352
 
 
1353
        vector<string> *typelist = saveTypeToList(_type);
 
1354
        addSubStringSeq(list,typelist);
 
1355
        delete typelist;
 
1356
 
 
1357
        sqprintf(list,"data");
 
1358
 
 
1359
        vector<string> *portlist = PortDesc_impl::saveToList();
 
1360
        addSubStringSeq(list,portlist);
 
1361
        delete portlist;
 
1362
 
 
1363
        return list;
 
1364
}