Statistics
| Branch: | Revision:

root / include / cgate.h @ fbe00e73

History | View | Annotate | Download (16.5 KB)

1
//==========================================================================
2
//   CGATE.H  -  header for
3
//                     OMNeT++/OMNEST
4
//            Discrete System Simulation in C++
5
//
6
//
7
//  Declaration of the following classes:
8
//    cGate       : module gate
9
//
10
//==========================================================================
11

    
12
/*--------------------------------------------------------------*
13
  Copyright (C) 1992-2008 Andras Varga
14
  Copyright (C) 2006-2008 OpenSim Ltd.
15

16
  This file is distributed WITHOUT ANY WARRANTY. See the file
17
  `license' for details on this and other legal matters.
18
*--------------------------------------------------------------*/
19

    
20
#ifndef __CGATE_H
21
#define __CGATE_H
22

    
23
#include <set>
24
#include <map>
25
#include "cobject.h"
26
#include "cstringpool.h"
27
#include "opp_string.h"
28
#include "simtime_t.h"
29

    
30
NAMESPACE_BEGIN
31

    
32
class cGate;
33
class cModule;
34
class cMessage;
35
class cChannelType;
36
class cChannel;
37
class cProperties;
38
class cDisplayString;
39
class cIdealChannel;
40
class cDatarateChannel;
41

    
42

    
43
//
44
// internal: gateId bitfield macros.
45
// See note in cgate.cc
46
//
47
#define GATEID_LBITS  20
48
#define GATEID_HBITS  (8*sizeof(int)-GATEID_LBITS)   // usually 12
49
#define GATEID_HMASK  ((~0)<<GATEID_LBITS)           // usually 0xFFF00000
50
#define GATEID_LMASK  (~GATEID_HMASK)                // usually 0x000FFFFF
51

    
52
#define MAX_VECTORGATES  ((1<<(GATEID_HBITS-1))-2)   // usually 2046
53
#define MAX_SCALARGATES  ((1<<(GATEID_LBITS-1))-2)   // usually ~500000
54
#define MAX_VECTORGATESIZE ((1<<(GATEID_LBITS-1))-1) // usually ~500000
55

    
56
/**
57
 * Represents a module gate. cGate object are created and managed by modules;
58
 * the user typically does not want to directly create or destroy cGate
59
 * objects. However, they are important if a simple module algorithm
60
 * needs to know about its surroundings.
61
 *
62
 * @ingroup SimCore
63
 */
64
class SIM_API cGate : public cObject, noncopyable
65
{
66
    friend class cModule;
67
    friend class cModuleGates;
68
    friend class cPlaceholderModule;
69

    
70
  public:
71
    /**
72
     * Gate type
73
     */
74
    enum Type {
75
        NONE = 0,
76
        INPUT = 'I',
77
        OUTPUT = 'O',
78
        INOUT = 'B'
79
    };
80

    
81
  protected:
82
    // internal
83
    struct SIM_API Name
84
    {
85
        opp_string name;  // "foo"
86
        opp_string namei; // "foo$i"
87
        opp_string nameo; // "foo$o"
88
        Type type;
89
        Name(const char *name, Type type);
90
        bool operator<(const Name& other) const;
91
    };
92

    
93
  public:
94
    // Internal data structure, only public for technical reasons (GateIterator).
95
    // One instance per module and per gate vector/gate pair/gate.
96
    // Note: gate name and type are factored out to a global pool.
97
    // Note2: to reduce sizeof(Desc), "size" might be stored in inputgatev[0],
98
    // although it might not be worthwhile the extra complication and CPU cycles.
99
    //
100
    struct Desc
101
    {
102
        cModule *ownerp;
103
        Name *namep;  // pooled (points into cModule::namePool)
104
        int size; // gate vector size, or -1 if scalar gate; actually allocated size is capacityFor(size)
105
        union { cGate *inputgate; cGate **inputgatev; };
106
        union { cGate *outputgate; cGate **outputgatev; };
107

    
108
        Desc() {ownerp=NULL; size=-1; namep=NULL; inputgate=outputgate=NULL;}
109
        bool inUse() const {return namep!=NULL;}
110
        Type getType() const {return namep->type;}
111
        bool isVector() const {return size>=0;}
112
        const char *nameFor(Type t) const {return (t==INOUT||namep->type!=INOUT) ? namep->name.c_str() : t==INPUT ? namep->namei.c_str() : namep->nameo.c_str();}
113
        int indexOf(const cGate *g) const {return (g->pos>>2)==-1 ? 0 : g->pos>>2;}
114
        bool deliverOnReceptionStart(const cGate *g) const {return g->pos&2;}
115
        Type getTypeOf(const cGate *g) const {return (g->pos&1)==0 ? INPUT : OUTPUT;}
116
        bool isInput(const cGate *g) const {return (g->pos&1)==0;}
117
        bool isOutput(const cGate *g) const {return (g->pos&1)==1;}
118
        int gateSize() const {return size>=0 ? size : 1;}
119
        void setInputGate(cGate *g) {ASSERT(getType()!=OUTPUT && !isVector()); inputgate=g; g->desc=this; g->pos=(-1<<2);}
120
        void setOutputGate(cGate *g) {ASSERT(getType()!=INPUT && !isVector()); outputgate=g; g->desc=this; g->pos=(-1<<2)|1;}
121
        void setInputGate(cGate *g, int index) {ASSERT(getType()!=OUTPUT && isVector()); inputgatev[index]=g; g->desc=this; g->pos=(index<<2);}
122
        void setOutputGate(cGate *g, int index) {ASSERT(getType()!=INPUT && isVector()); outputgatev[index]=g; g->desc=this; g->pos=(index<<2)|1;}
123
        static int capacityFor(int size) {return size<8 ? (size+1)&~1 : size<32 ? (size+3)&~3 : size<256 ? (size+15)&~15 : (size+63)&~63;}
124
    };
125

    
126
  protected:
127
    Desc *desc; // descriptor of gate/gate vector, stored in cModule
128
    int pos;    // b0: input(0) or output(1); b1: deliverOnReceptionStart bit;
129
                // rest (pos>>2): array index, or -1 if scalar gate
130

    
131
    cChannel *channelp; // channel object (if exists)
132
    cGate *prevgatep;   // previous and next gate in the path
133
    cGate *nextgatep;
134

    
135
  protected:
136
    // internal: constructor is protected because only cModule is allowed to create instances
137
    explicit cGate();
138

    
139
    // also protected: only cModule is allowed to delete gates
140
    virtual ~cGate();
141

    
142
    // internal
143
    static void clearFullnamePool();
144

    
145
    // internal
146
    void installChannel(cChannel *chan);
147

    
148
    // internal
149
    void checkChannels() const;
150

    
151
  public:
152
    /** @name Redefined cObject member functions */
153
    //@{
154
    /**
155
     * Returns the name of the the gate without the gate index in brackets.
156
     */
157
    virtual const char *getName() const;
158

    
159
    /**
160
     * Returns the full name of the gate, which is getName() plus the
161
     * index in square brackets (e.g. "out[4]"). Redefined to add the
162
     * index.
163
     */
164
    virtual const char *getFullName() const;
165

    
166
    /**
167
     * Calls v->visit(this) for each contained object.
168
     * See cObject for more details.
169
     */
170
    virtual void forEachChild(cVisitor *v);
171

    
172
    /**
173
     * Produces a one-line description of the object's contents.
174
     * See cObject for more details.
175
     */
176
    virtual std::string info() const;
177

    
178
    /**
179
     * Returns the owner module of this gate.
180
     */
181
    virtual cObject *getOwner() const;
182
    //@}
183

    
184
    /**
185
     * This function is called internally by the send() functions and
186
     * channel classes' deliver() to deliver the message to its destination.
187
     * A false return value means that the message object should be deleted
188
     * by the caller. (This is used e.g. with parallel simulation, for
189
     * messages leaving the partition.)
190
     */
191
    virtual bool deliver(cMessage *msg, simtime_t at);
192

    
193
    /** @name Connecting the gate. */
194
    //@{
195
    /**
196
     * Connects the gate to another gate, using the given channel object
197
     * (if one is specified). This method can be used to manually create
198
     * connections for dynamically created modules.
199
     *
200
     * This method invokes callInitialize() on the channel object, unless the
201
     * compound module containing this connection is not yet initialized
202
     * (then it assumes that this channel will be initialized as part of the
203
     * compound module initialization process.) To leave the channel
204
     * uninitialized, specify true for the leaveUninitialized parameter.
205
     *
206
     * If the gate is already connected, an error will occur. The gate
207
     * argument cannot be NULL, that is, you cannot use this function
208
     * to disconnect a gate; use disconnect() for that.
209
     *
210
     * Note: When you set channel parameters after channel initialization,
211
     * make sure the channel class is implemented so that the changes take
212
     * effect; i.e. the channel should either override and properly handle
213
     * handleParameterChange(), or should not cache any values from parameters.
214
     */
215
    cChannel *connectTo(cGate *gate, cChannel *channel=NULL, bool leaveUninitialized=false);
216

    
217
    /**
218
     * Disconnects the gate, and also deletes the associated channel object
219
     * if one has been set. disconnect() must be invoked on the source gate
220
     * ("from" side) of the connection.
221
     *
222
     * The method has no effect if the gate is not connected.
223
     */
224
    void disconnect();
225

    
226
    /**
227
     * Disconnects the gate, then connects it again to the same gate, with the
228
     * given channel object (if not NULL). The gate must be connected.
229
     *
230
     * @see connectTo()
231
     */
232
    cChannel *reconnectWith(cChannel *channel, bool leaveUninitialized=false);
233

    
234
    /**
235
     * DEPRECATED: Use reconnectWith() instead.
236
     */
237
    _OPPDEPRECATED void setChannel(cChannel *channel) {reconnectWith(channel);}
238
    //@}
239

    
240
    /** @name Information about the gate. */
241
    //@{
242
    /**
243
     * Returns the gate name without index and potential "$i"/"$o" suffix.
244
     */
245
    const char *getBaseName() const;
246

    
247
    /**
248
     * Returns the suffix part of the gate name ("$i", "$o" or "").
249
     */
250
    const char *getNameSuffix() const;
251

    
252
    /**
253
     * Returns the properties for this gate. Properties cannot be changed
254
     * at runtime.
255
     */
256
    cProperties *getProperties() const;
257

    
258
    /**
259
     * Returns the gate's type, cGate::INPUT or cGate::OUTPUT. (It never returns
260
     * cGate::INOUT, because a cGate object is always either the input or
261
     * the output half of an inout gate ("name$i" or "name$o").
262
     */
263
    Type getType() const  {return desc->getTypeOf(this);}
264

    
265
    /**
266
     * Returns the given type as a string.
267
     */
268
    static const char *getTypeName(Type t);
269

    
270
    /**
271
     * Returns a pointer to the owner module of the gate.
272
     */
273
    cModule *getOwnerModule() const;
274

    
275
    /**
276
     * Returns the gate ID, which uniquely identifies the gate within the
277
     * module. IDs are guaranteed to be contiguous within a gate vector:
278
     * <tt>module->gate(id+index) == module->gate(id)+index</tt>.
279
     *
280
     * Gate IDs are stable: they are guaranteed not to change during
281
     * simulation. (This is a new feature of \opp 4.0. In earlier releases,
282
     * gate IDs could change when the containing gate vector was resized.)
283
     *
284
     * Note: As of \opp 4.0, gate IDs are no longer small integers, and
285
     * cannot be used for iterating over the gates of a module.
286
     * Use cModule::GateIterator for iteration.
287
     */
288
    int getId() const;
289

    
290
    /**
291
     * Returns true if the gate is part of a gate vector.
292
     */
293
    bool isVector() const  {return desc->isVector();}
294

    
295
    /**
296
     * If the gate is part of a gate vector, returns the gate's index in the vector.
297
     * Otherwise, it returns 0.
298
     */
299
    int getIndex() const  {return desc->indexOf(this);}
300

    
301
    /**
302
     * If the gate is part of a gate vector, returns the size of the vector.
303
     * For non-vector gates it returns 1.
304
     *
305
     * The gate vector size can also be obtained by calling the cModule::gateSize().
306
     */
307
    int getVectorSize() const  {return desc->gateSize();}
308

    
309
    /**
310
     * Alias for getVectorSize().
311
     */
312
    int size() const  {return getVectorSize();}
313

    
314
    /**
315
     * Returns the channel object attached to this gate, or NULL if there is
316
     * no channel. This is the channel between this gate and this->getNextGate(),
317
     * that is, channels are stored on the "from" side of the connections.
318
     */
319
    cChannel *getChannel() const  {return channelp;}
320

    
321
    /**
322
     * This method may only be invoked on input gates of simple modules.
323
     * Messages with nonzero length then have a nonzero
324
     * transmission duration (and thus, reception duration on the other
325
     * side of the connection). By default, the delivery of the message
326
     * to the module marks the end of the reception. Setting this bit will cause
327
     * the channel to deliver the message to the module at the start of the
328
     * reception. The duration that the reception will take can be extracted
329
     * from the message object, by its getDuration() method.
330
     */
331
    void setDeliverOnReceptionStart(bool d);
332

    
333
    /**
334
     * Returns whether messages delivered through this gate will mark the
335
     * start or the end of the reception process (assuming nonzero message length
336
     * and data rate on the channel.)
337
     *
338
     * @see setDeliverOnReceptionStart()
339
     */
340
    bool getDeliverOnReceptionStart() const  {return pos&2;}
341
    //@}
342

    
343
    /** @name Transmission state. */
344
    //@{
345
    /**
346
     * Typically invoked on an output gate, this method returns <i>the</i>
347
     * channel in the connection path that supports datarate (as determined
348
     * by cChannel::isTransmissionChannel(); it is guaranteed that there can be
349
     * at most one such channel per path). If there is no such channel,
350
     * an error is thrown.
351
     *
352
     * This method only checks the segment of the connection path that
353
     * <i>starts</i> at this gate, so, for example, it is an error to invoke
354
     * it on a simple module input gate.
355
     *
356
     * Note: this method searches the connection path linearly, so at
357
     * performance-critical places it may be better to cache its return
358
     * value (provided that connections are not removed or created dynamically
359
     * during simulation.)
360
     *
361
     * @see cChannel::isTransmissionChannel()
362
     */
363
    cChannel *getTransmissionChannel() const;
364

    
365
    /**
366
     * Like getTransmissionChannel(), but returns NULL instead of throwing
367
     * an error if there is no transmission channel in the path.
368
     */
369
    cChannel *findTransmissionChannel() const;
370

    
371
    /**
372
     * Typically invoked on an input gate, this method searches the reverse
373
     * path (i.e. calls getPreviousGate() repeatedly) for the transmission
374
     * channel. It is guaranteed that there can be at most one such channel
375
     * per path. If no transmission channel is found, the method throws an error.
376
     *
377
     * @see getTransmissionChannel(), cChannel::isTransmissionChannel()
378
     */
379
    cChannel *getIncomingTransmissionChannel() const;
380

    
381
    /**
382
     * Like getIncomingTransmissionChannel(), but returns NULL instead of
383
     * throwing an error if there is no transmission channel in the reverse
384
     * path.
385
     */
386
    cChannel *findIncomingTransmissionChannel() const;
387
    //@}
388

    
389
    /** @name Gate connectivity. */
390
    //@{
391

    
392
    /**
393
     * Returns the previous gate in the series of connections (the path) that
394
     * contains this gate, or a NULL pointer if this gate is the first one in the path.
395
     * (E.g. for a simple module output gate, this function will return NULL.)
396
     */
397
    cGate *getPreviousGate() const {return prevgatep;}
398

    
399
    /**
400
     * Returns the next gate in the series of connections (the path) that
401
     * contains this gate, or a NULL pointer if this gate is the last one in the path.
402
     * (E.g. for a simple module input gate, this function will return NULL.)
403
     */
404
    cGate *getNextGate() const   {return nextgatep;}
405

    
406
    /**
407
     * Return the ultimate source of the series of connections
408
     * (the path) that contains this gate.
409
     */
410
    cGate *getPathStartGate() const;
411

    
412
    /**
413
     * Return the ultimate destination of the series of connections
414
     * (the path) that contains this gate.
415
     */
416
    cGate *getPathEndGate() const;
417

    
418
    /**
419
     * Determines if a given module is in the path containing this gate.
420
     */
421
    bool pathContains(cModule *module, int gateId=-1);
422

    
423
    /**
424
     * Returns true if the gate is connected outside (i.e. to one of its
425
     * sibling modules or to the parent module).
426
     *
427
     * This means that for an input gate, getPreviousGate() must be non-NULL; for an output
428
     * gate, getNextGate() must be non-NULL.
429
     */
430
    bool isConnectedOutside() const;
431

    
432
    /**
433
     * Returns true if the gate (of a compound module) is connected inside
434
     * (i.e. to one of its submodules).
435
     *
436
     * This means that for an input gate, getNextGate() must be non-NULL; for an output
437
     * gate, getPreviousGate() must be non-NULL.
438
     */
439
    bool isConnectedInside() const;
440

    
441
    /**
442
     * Returns true if the gate fully connected. For a compound module gate
443
     * this means both isConnectedInside() and isConnectedOutside() are true;
444
     * for a simple module, only isConnectedOutside() is checked.
445
     */
446
    bool isConnected() const;
447

    
448
    /**
449
     * Returns true if the path (chain of connections) containing this gate
450
     * starts and ends at a simple module.
451
     */
452
    bool isPathOK() const;
453
    //@}
454

    
455
    /** @name Display string. */
456
    //@{
457
    /**
458
     * Returns the display string for the gate, which controls the appearance
459
     * of the connection arrow starting from gate. The display string is stored
460
     * in the channel associated with the connection. If there is no channel,
461
     * this call creates an installs a cIdealChannel to hold the display string.
462
     */
463
    cDisplayString& getDisplayString();
464

    
465
    /**
466
     * Shortcut to <tt>getDisplayString().set(dispstr)</tt>.
467
     */
468
    void setDisplayString(const char *dispstr);
469
    //@}
470
};
471

    
472
NAMESPACE_END
473

    
474
#endif
475