chiark / gitweb /
undo broken deletion
[trains.git] / layout / graph-data.h
1 /*
2  */
3
4 #ifndef GRAPH_DATA_H
5 #define GRAPH_DATA_H
6
7
8 typedef struct Edge Edge;
9 typedef struct Segment Segment;
10 typedef struct MovFeat MovFeat;
11 typedef struct EdgeEnd EdgeEnd;
12 typedef struct Node Node;
13 typedef struct NodeList NodeList;
14 typedef struct NodeSide NodeSide;
15
16 struct Segment {
17   const char *segname; /* 0 if unknown (usually elided by extractgraph) */
18   int n_movfeats;
19   MovFeat *movfeats; /* [0] is fixed */
20   MovFeat *starfeature; /* set by movfeatmultedges */
21 };
22
23 struct MovFeat {
24   Segment *segment;
25   const char *movfeat; /* 0 if fixed */
26   int n_positions;
27 };
28
29 struct EdgeEnd {
30   EdgeEnd *back, *next; /* other ends at same side of same node */
31   Edge *edge; /* edge->ends[end].edge==edge */
32   int end; /* edge->ends[end].edge==end */
33   NodeSide *node;
34 };
35
36 struct Edge {
37   const char *pname;
38   double distance;
39   MovFeat *subseg;
40   int movpos; /* 0 if fixed */
41   EdgeEnd ends[2];
42 };
43
44 struct NodeSide {
45   Node *node; /* node->edges[side].node==node */
46   int side; /* node->edges[side].side==side */
47   EdgeEnd *head, *tail;
48 };
49
50 struct Node {
51   const char *pname;
52   Node *back, *next;
53   NodeSide sides[2];
54 };
55
56 struct NodeList {
57   Node *head, *tail;
58 };
59
60 extern NodeList all_nodes;
61 extern int next_nodenum, next_edgenum;
62
63
64 #define FOR_ALL_NODES(node) for (node=all_nodes.head; node; node=node->next)
65 #define FOR_BOTH(sideend) for (sideend=0; sideend<2; sideend++)
66
67 #define FOR_NODE_EDGEENDS(side,edgeend, node)   \
68   FOR_BOTH(side)                                \
69     FOR_SIDE_EDGEENDS(edgeend, (node),side)
70
71 #define FOR_SIDE_EDGEENDS(edgeend, node,side) \
72   for (edgeend=(node)->sides[(side)].head; edgeend; edgeend=edgeend->next)
73
74 #define FOR_SEGMENT_MOVFEATS(i,f, segment) \
75   for (i=0, f=segment->movfeats; i < segment->n_movfeats; i++, f++)
76
77 /* Iteration over edges: 
78  *   FOR_ALL_NODES(node) {
79  *     FOR_EDGES(edge, node,side,edgeend)
80  *       <statement>|<block>
81  *   }
82  * arranges execute statement/block once for each edge, setting edge
83  * appropriately.  edgeend must be of type EdgeEnd*, and side of type
84  * int; these are used as working variables by FOR_EDGES.
85  */
86 #define FOR_EDGES(edge, node,side,edgeend)              \
87     FOR_NODE_EDGEENDS(side,edgeend, node)                       \
88       if ((edge= edgeend->edge), edgeend->end) {        \
89         /* do each edge once, from end 0, only */       \
90       } else
91      
92
93 #endif /*GRAPH_DATA_H*/