1 #include <stdlib.h>
2 #include <string.h>
3 #include "ring.h"
4 
ring_alloc(Ring * ring,int capacity)5 void ring_alloc(Ring *ring, int capacity) {
6     ring->capacity = capacity;
7     ring->start = 0;
8     ring->end = 0;
9     ring->data = (RingEntry *)calloc(capacity, sizeof(RingEntry));
10 }
11 
ring_free(Ring * ring)12 void ring_free(Ring *ring) {
13     free(ring->data);
14 }
15 
ring_empty(Ring * ring)16 int ring_empty(Ring *ring) {
17     return ring->start == ring->end;
18 }
19 
ring_full(Ring * ring)20 int ring_full(Ring *ring) {
21     return ring->start == (ring->end + 1) % ring->capacity;
22 }
23 
ring_size(Ring * ring)24 int ring_size(Ring *ring) {
25     if (ring->end >= ring->start) {
26         return ring->end - ring->start;
27     }
28     else {
29         return ring->capacity - (ring->start - ring->end);
30     }
31 }
32 
ring_grow(Ring * ring)33 void ring_grow(Ring *ring) {
34     Ring new_ring;
35     RingEntry entry;
36     ring_alloc(&new_ring, ring->capacity * 2);
37     while (ring_get(ring, &entry)) {
38         ring_put(&new_ring, &entry);
39     }
40     free(ring->data);
41     ring->capacity = new_ring.capacity;
42     ring->start = new_ring.start;
43     ring->end = new_ring.end;
44     ring->data = new_ring.data;
45 }
46 
ring_put(Ring * ring,RingEntry * entry)47 void ring_put(Ring *ring, RingEntry *entry) {
48     if (ring_full(ring)) {
49         ring_grow(ring);
50     }
51     RingEntry *e = ring->data + ring->end;
52     memcpy(e, entry, sizeof(RingEntry));
53     ring->end = (ring->end + 1) % ring->capacity;
54 }
55 
ring_put_block(Ring * ring,int p,int q,int x,int y,int z,int w)56 void ring_put_block(Ring *ring, int p, int q, int x, int y, int z, int w) {
57     RingEntry entry;
58     entry.type = BLOCK;
59     entry.p = p;
60     entry.q = q;
61     entry.x = x;
62     entry.y = y;
63     entry.z = z;
64     entry.w = w;
65     ring_put(ring, &entry);
66 }
67 
ring_put_light(Ring * ring,int p,int q,int x,int y,int z,int w)68 void ring_put_light(Ring *ring, int p, int q, int x, int y, int z, int w) {
69     RingEntry entry;
70     entry.type = LIGHT;
71     entry.p = p;
72     entry.q = q;
73     entry.x = x;
74     entry.y = y;
75     entry.z = z;
76     entry.w = w;
77     ring_put(ring, &entry);
78 }
79 
ring_put_key(Ring * ring,int p,int q,int key)80 void ring_put_key(Ring *ring, int p, int q, int key) {
81     RingEntry entry;
82     entry.type = KEY;
83     entry.p = p;
84     entry.q = q;
85     entry.key = key;
86     ring_put(ring, &entry);
87 }
88 
ring_put_commit(Ring * ring)89 void ring_put_commit(Ring *ring) {
90     RingEntry entry;
91     entry.type = COMMIT;
92     ring_put(ring, &entry);
93 }
94 
ring_put_exit(Ring * ring)95 void ring_put_exit(Ring *ring) {
96     RingEntry entry;
97     entry.type = EXIT;
98     ring_put(ring, &entry);
99 }
100 
ring_get(Ring * ring,RingEntry * entry)101 int ring_get(Ring *ring, RingEntry *entry) {
102     if (ring_empty(ring)) {
103         return 0;
104     }
105     RingEntry *e = ring->data + ring->start;
106     memcpy(entry, e, sizeof(RingEntry));
107     ring->start = (ring->start + 1) % ring->capacity;
108     return 1;
109 }
110