chiark / gitweb /
include crossing A5/A6
[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   int u;
22 };
23
24 struct MovFeat {
25   Segment *segment;
26   const char *movfeat; /* 0 if fixed */
27   int n_positions;
28 };
29
30 struct EdgeEnd {
31   EdgeEnd *back, *next; /* other ends at same side of same node */
32   Edge *edge; /* edge->ends[end].edge==edge */
33   int end; /* edge->ends[end].edge==end */
34   NodeSide *node;
35 };
36
37 struct Edge {
38   const char *pname;
39   double distance;
40   MovFeat *subseg;
41   int movpos; /* 0 if fixed */
42   EdgeEnd ends[2];
43 };
44
45 struct NodeSide {
46   Node *node; /* node->edges[side].node==node */
47   int side; /* node->edges[side].side==side */
48   EdgeEnd *head, *tail;
49 };
50
51 struct Node {
52   const char *pname;
53   Node *back, *next;
54   double x,y,a;
55   int layermin,layermax;
56   NodeSide sides[2];
57 };
58
59 struct NodeList {
60   Node *head, *tail;
61 };
62
63 extern NodeList all_nodes;
64 extern int next_nodenum, next_edgenum;
65
66 extern Segment *all_segments[];
67
68
69 #define FOR_ALL_NODES(node) for (node=all_nodes.head; node; node=node->next)
70 #define FOR_BOTH(sideend) for (sideend=0; sideend<2; sideend++)
71
72 #define FOR_NODE_EDGEENDS(side,edgeend, node)   \
73   FOR_BOTH(side)                                \
74     FOR_SIDE_EDGEENDS(edgeend, (node),side)
75
76 #define FOR_SIDE_EDGEENDS(edgeend, node,side) \
77   for (edgeend=(node)->sides[(side)].head; edgeend; edgeend=edgeend->next)
78
79 #define FOR_SEGMENT_MOVFEATS(i,f, segment) \
80   for (i=0, f=segment->movfeats; i < segment->n_movfeats; i++, f++)
81
82 /* Iteration over edges: 
83  *   FOR_ALL_NODES(node) {
84  *     FOR_EDGES(edge, node,side,edgeend)
85  *       <statement>|<block>
86  *   }
87  * arranges execute statement/block once for each edge, setting edge
88  * appropriately.  edgeend must be of type EdgeEnd*, and side of type
89  * int; these are used as working variables by FOR_EDGES.
90  */
91 #define FOR_EDGES(edge, node,side,edgeend)              \
92     FOR_NODE_EDGEENDS(side,edgeend, node)                       \
93       if ((edge= edgeend->edge), edgeend->end) {        \
94         /* do each edge once, from end 0, only */       \
95       } else
96
97 #define FOR_ALL_SEGMENTS(segmentp,segment)      \
98   for (segmentp=all_segments;                   \
99        (segment= *segmentp);                    \
100        segmentp++)
101
102 #endif /*GRAPH_DATA_H*/