1 #ifndef R_SPACES_H
2 #define R_SPACES_H
3
4 #define R_SPACES_MAX 512
5
6 #include "r_util.h"
7
8 #ifdef __cplusplus
9 extern "C" {
10 #endif
11
12 /*
13 * RSpaces represents a set of Spaces.
14 * A Space is used to group similar objects and it can have a name. Name
15 * "*"/""/NULL is reserved to indicate "all spaces".
16 *
17 * You can have groups of "meta" (e.g. bin meta, format meta, etc.), groups of
18 * zign info, groups of flags, etc.
19 *
20 * It is possible to hook into the RSpaces functions by using REvent.
21 * R_SPACE_EVENT_COUNT: called when you need to count how many elements there are in a given RSpace
22 * R_SPACE_EVENT_RENAME: called when renaming a RSpace with an oldname to a newname
23 * R_SPACE_EVENT_UNSET: called when deleting a RSpace with a given name
24 */
25
26 typedef struct r_space_t {
27 char *name;
28 RBNode rb;
29 } RSpace;
30
31 typedef enum {
32 R_SPACE_EVENT_COUNT = 1,
33 R_SPACE_EVENT_RENAME,
34 R_SPACE_EVENT_UNSET,
35 } RSpaceEventType;
36
37 typedef struct r_space_event_t {
38 union {
39 struct {
40 const RSpace *space;
41 } count;
42 struct {
43 const RSpace *space;
44 } unset;
45 struct {
46 const RSpace *space;
47 const char *oldname;
48 const char *newname;
49 } rename;
50 } data;
51 int res;
52 } RSpaceEvent;
53
54 typedef struct r_spaces_t {
55 const char *name;
56 RSpace *current;
57 RBTree spaces;
58 RList *spacestack;
59 REvent *event;
60 } RSpaces;
61
62 // Create a new RSpaces with the given name
63 R_API RSpaces *r_spaces_new(const char *name);
64 // Initialize an existing RSpaces with the given name
65 R_API bool r_spaces_init(RSpaces *sp, const char *name);
66 // Finalize an existing RSpaces
67 R_API void r_spaces_fini(RSpaces *sp);
68 // Finalize and free an existing RSpaces
69 R_API void r_spaces_free(RSpaces *sp);
70 // Delete all spaces
71 R_API void r_spaces_purge(RSpaces *sp);
72 // Get the RSpace with the given name
73 R_API RSpace *r_spaces_get(RSpaces *sp, const char *name);
74 // Add a new RSpace if one does not already exist, otherwise return the existing one
75 R_API RSpace *r_spaces_add(RSpaces *sp, const char *name);
76 // Add and select a new RSpace if one does not already exist, otherwise return and select the existing one
77 R_API RSpace *r_spaces_set(RSpaces *sp, const char *name);
78 // Remove the RSpace with the given name or all of them if name is NULL
79 R_API bool r_spaces_unset(RSpaces *sp, const char *name);
80 // Change the name of RSpace with oname to nname
81 R_API bool r_spaces_rename(RSpaces *sp, const char *oname, const char *nname);
82 // Count the elements that belong to the RSpace with the given name
83 R_API int r_spaces_count(RSpaces *sp, const char *name);
84 // Add/Select the RSpace with the given name and save the current one in the history
85 R_API bool r_spaces_push(RSpaces *sp, const char *name);
86 // Select the RSpace that was set before the current one
87 R_API bool r_spaces_pop(RSpaces *sp);
88
r_spaces_current(RSpaces * sp)89 static inline RSpace *r_spaces_current(RSpaces *sp) {
90 return sp->current;
91 }
92
r_spaces_current_name(RSpaces * sp)93 static inline const char *r_spaces_current_name(RSpaces *sp) {
94 return sp->current? sp->current->name: "*";
95 }
96
r_spaces_is_empty(RSpaces * sp)97 static inline bool r_spaces_is_empty(RSpaces *sp) {
98 RBIter it = r_rbtree_first (sp->spaces);
99 return it.len == 0;
100 }
101
102 typedef RBIter RSpaceIter;
103 #define r_spaces_foreach(sp, it, s) \
104 r_rbtree_foreach ((sp)->spaces, (it), (s), RSpace, rb)
105
106 #ifdef __cplusplus
107 }
108 #endif
109
110 #endif // R_SPACES_H
111