Merged with current edge.
[clinton/Smoothieware.git] / src / modules / robot / BlockQueue.h
1 #pragma once
2
3 class Block;
4
5 class BlockQueue {
6
7 // friend classes
8 friend class Planner;
9 friend class Conveyor;
10
11 public:
12 BlockQueue();
13 BlockQueue(unsigned int length);
14
15 ~BlockQueue();
16
17 /*
18 * direct accessors
19 */
20 Block& head();
21 Block& tail();
22
23 void push_front(Block&) __attribute__ ((warning("Not thread-safe if pop_back() is used in ISR context!"))); // instead, prepare(head_ref()); produce_head();
24 Block& pop_back(void) __attribute__ ((warning("Not thread-safe if head_ref() is used to prepare new items, or push_front() is used in ISR context!"))); // instead, consume(tail_ref()); consume_tail();
25
26 /*
27 * pointer accessors
28 */
29 Block* head_ref();
30 Block* tail_ref();
31
32 void produce_head(void);
33 void consume_tail(void);
34
35 /*
36 * queue status
37 */
38 bool is_empty(void) const;
39 bool is_full(void) const;
40
41 /*
42 * resize
43 *
44 * returns true on success, or false if queue is not empty or not enough memory available
45 */
46 bool resize(unsigned int);
47
48 /*
49 * provide
50 * Block* - new buffer pointer
51 * int length - number of items in buffer (NOT size in bytes!)
52 *
53 * cause BlockQueue to use a specific memory location instead of allocating its own
54 *
55 * returns true on success, or false if queue is not empty
56 */
57 //bool provide(Block*, unsigned int length);
58
59 protected:
60 /*
61 * these functions are protected as they should only be used internally
62 * or in extremely specific circumstances
63 */
64 Block& item(unsigned int);
65 Block* item_ref(unsigned int);
66
67 unsigned int next(unsigned int) const;
68 unsigned int prev(unsigned int) const;
69
70 /*
71 * buffer variables
72 */
73 unsigned int length;
74
75 volatile unsigned int head_i;
76 volatile unsigned int tail_i;
77 volatile unsigned int isr_tail_i;
78
79 private:
80 Block* ring;
81 };