ObjectivelyMVC 0.1.0
Object oriented MVC framework for OpenGL, SDL2 and GNU C
Data Structures | Macros | Functions
Selector.c File Reference
#include <assert.h>
#include <string.h>
#include <Objectively/Hash.h>
#include <Objectively/MutableArray.h>
#include <Objectively/MutableSet.h>
#include "Log.h"
#include "Selector.h"
#include "View.h"

Go to the source code of this file.

Data Structures

struct  Match
 A context for View matching. More...
 
struct  Selection
 A context for View selection. More...
 

Macros

#define _Class   _Selector
 

Functions

static Set * __select (View *view, Selection *selection)
 Recursively selects Views by iterating the SelectorSequences in the given Selection. More...
 
static _Bool _matchesView (const View *view, Match *match)
 ViewEnumerator for matchesView. More...
 
static Set * _select (const Selector *self, View *view)
 
Class * _Selector (void)
 
static Order compareTo (const Selector *self, const Selector *other)
 
static void dealloc (Object *self)
 
static String * description (const Object *self)
 
static void enumerateSelection (const Selector *self, View *view, ViewEnumerator enumerator, ident data)
 
static int hash (const Object *self)
 
static void initialize (Class *clazz)
 
static SelectorinitWithRule (Selector *self, const char *rule)
 
static _Bool isEqual (const Object *self, const Object *other)
 
static _Bool matchesView (const Selector *self, const View *view)
 
static Array * parse (const char *rules)
 
static int specificity (const Selector *selector)
 

Macro Definition Documentation

◆ _Class

#define _Class   _Selector

Definition at line 35 of file Selector.c.

Function Documentation

◆ __select()

static Set * __select ( View view,
Selection selection 
)
static

Recursively selects Views by iterating the SelectorSequences in the given Selection.

Definition at line 318 of file Selector.c.

318 {
319
320 const SelectorSequence *sequence = $(selection->sequences, objectAtIndex, selection->sequence);
321
322 if ($(sequence, matchesView, view)) {
323
324 switch (sequence->right) {
326 break;
327
329 selection->sequence++;
330 $(view, enumerateDescendants, (ViewEnumerator) __select, selection);
331 break;
332
334 selection->sequence++;
335 $(view, enumerateSubviews, (ViewEnumerator) __select, selection);
336 break;
337
339 selection->sequence++;
340 $(view, enumerateSiblings, (ViewEnumerator) __select, selection);
341 break;
342
344 selection->sequence++;
345 $(view, enumerateAdjacent, (ViewEnumerator) __select, selection);
346 break;
347
349 $(selection->selection, addObject, view);
350 break;
351 }
352 }
353
354 $(view, enumerateSubviews, (ViewEnumerator) __select, selection);
355
356 return (Set *) selection->selection;
357}
static Set * __select(View *view, Selection *selection)
Recursively selects Views by iterating the SelectorSequences in the given Selection.
Definition: Selector.c:318
@ SequenceCombinatorTerminal
@ SequenceCombinatorAdjacent
@ SequenceCombinatorNone
@ SequenceCombinatorChild
@ SequenceCombinatorDescendent
@ SequenceCombinatorSibling
void(* ViewEnumerator)(View *view, ident data)
A function type for View enumeration.
Definition: Types.h:55
MutableSet * selection
Definition: Selector.c:312
const Array * sequences
Definition: Selector.c:310
size_t sequence
Definition: Selector.c:311
_Bool matchesView(const Selector *self, View *view)
SelectorSequences are comprised of one or more SimpleSelectors.
SequenceCombinator right
void enumerateSiblings(const View *self, ViewEnumerator enumerator, ident data)
Enumerates all siblings of this View, applying enumerator to each.
Definition: View.c:665
void enumerateDescendants(const View *self, ViewEnumerator enumerator, ident data)
Enumerates all descendants of this View, applying enumerator to each.
Definition: View.c:647
void enumerateAdjacent(const View *self, ViewEnumerator enumerator, ident data)
Enumerates adjacent siblings of this View, applying enumerator to each.
Definition: View.c:601
void enumerateSubviews(const View *self, ViewEnumerator enumerator, ident data)
Enumerates all subviews of this View, applying enumerator to each.
Definition: View.c:685

◆ _matchesView()

static _Bool _matchesView ( const View view,
Match match 
)
static

ViewEnumerator for matchesView.

Definition at line 217 of file Selector.c.

217 {
218
219 const SelectorSequence *sequence = $(match->sequences, objectAtIndex, match->sequence);
220
221 if ($(sequence, matchesView, view)) {
222
223 switch (sequence->left) {
225 match->match = true;
226 break;
227
229 match->sequence--;
231 break;
232
234 match->sequence--;
236 break;
237
239 match->sequence--;
241 break;
242
244 match->sequence--;
246 break;
247
249 break;
250 }
251 }
252
253 return match->match;
254}
static _Bool _matchesView(const View *view, Match *match)
ViewEnumerator for matchesView.
Definition: Selector.c:217
_Bool match
Definition: Selector.c:211
const Array * sequences
Definition: Selector.c:209
size_t sequence
Definition: Selector.c:210
SequenceCombinator left
The combinators.
void enumerateSuperview(const View *self, ViewEnumerator enumerator, ident data)
Enumerates the superview of this View, if any, applying enumerator to it.
Definition: View.c:699
void enumerateAncestors(const View *self, ViewEnumerator enumerator, ident data)
Enumerates all ancestors of this View, applying enumerator to each.
Definition: View.c:621

◆ _select()

static Set * _select ( const Selector self,
View view 
)
static

Definition at line 364 of file Selector.c.

364 {
365
366 assert(view);
367
368 return __select(view, &(Selection) {
369 .sequences = self->sequences,
370 .selection = $$(MutableSet, set)
371 });
372}
A context for View selection.
Definition: Selector.c:309
Array * sequences
The sequences.
Definition: Selector.h:65

◆ _Selector()

Class * _Selector ( void  )

Definition at line 398 of file Selector.c.

398 {
399 static Class *clazz;
400 static Once once;
401
402 do_once(&once, {
403 clazz = _initialize(&(const ClassDef) {
404 .name = "Selector",
405 .superclass = _Object(),
406 .instanceSize = sizeof(Selector),
407 .interfaceOffset = offsetof(Selector, interface),
408 .interfaceSize = sizeof(SelectorInterface),
410 });
411 });
412
413 return clazz;
414}
static void initialize(Class *clazz)
Definition: Selector.c:379
Selectors are comprised of one or more SelectorSequences.
Definition: Selector.h:49

◆ compareTo()

static Order compareTo ( const Selector self,
const Selector other 
)
static

Definition at line 149 of file Selector.c.

149 {
150
151 assert(other);
152
153 if (self->specificity < other->specificity) {
154 return OrderAscending;
155 } else if (self->specificity > other->specificity) {
156 return OrderDescending;
157 }
158
159 return OrderSame;
160}
int specificity
The specificity.
Definition: Selector.h:76

◆ dealloc()

static void dealloc ( Object *  self)
static
See also
Object::dealloc(Object *)

Definition at line 42 of file Selector.c.

42 {
43
44 Selector *this = (Selector *) self;
45
46 release(this->sequences);
47 free(this->rule);
48
49 super(Object, self, dealloc);
50}
static void dealloc(Object *self)
Definition: Selector.c:42

◆ description()

static String * description ( const Object *  self)
static
See also
Object::description(const Object *)

Definition at line 55 of file Selector.c.

55 {
56
57 const Selector *this = (Selector *) self;
58
59 return str(this->rule);
60}

◆ enumerateSelection()

static void enumerateSelection ( const Selector self,
View view,
ViewEnumerator  enumerator,
ident  data 
)
static

Definition at line 166 of file Selector.c.

166 {
167
168 assert(enumerator);
169
170 Set *selection = $(self, select, view);
171 assert(selection);
172
173 Array *array = $(selection, allObjects);
174 assert(array);
175
176 for (size_t i = 0; i < array->count; i++) {
177 enumerator($(array, objectAtIndex, i), data);
178 }
179
180 release(array);
181 release(selection);
182}
Array * select(const Selector *self, View *view)

◆ hash()

static int hash ( const Object *  self)
static
See also
Object::hash(const Object *)

Definition at line 65 of file Selector.c.

65 {
66
67 Selector *this = (Selector *) self;
68
69 return HashForCString(HASH_SEED, this->rule);
70}

◆ initialize()

static void initialize ( Class *  clazz)
static
See also
Class::initialize(Class *)

Definition at line 379 of file Selector.c.

379 {
380
381 ((ObjectInterface *) clazz->interface)->dealloc = dealloc;
382 ((ObjectInterface *) clazz->interface)->description = description;
383 ((ObjectInterface *) clazz->interface)->hash = hash;
384 ((ObjectInterface *) clazz->interface)->isEqual = isEqual;
385
386 ((SelectorInterface *) clazz->interface)->enumerateSelection = enumerateSelection;
387 ((SelectorInterface *) clazz->interface)->compareTo = compareTo;
388 ((SelectorInterface *) clazz->interface)->initWithRule = initWithRule;
389 ((SelectorInterface *) clazz->interface)->matchesView = matchesView;
390 ((SelectorInterface *) clazz->interface)->parse = parse;
391 ((SelectorInterface *) clazz->interface)->select = _select;
392}
static Set * _select(const Selector *self, View *view)
Definition: Selector.c:364
static String * description(const Object *self)
Definition: Selector.c:55
static _Bool isEqual(const Object *self, const Object *other)
Definition: Selector.c:75
static int hash(const Object *self)
Definition: Selector.c:65
Selector * initWithRule(Selector *self, const char *rule)
Initializes this Selector with the given rule.
Definition: Selector.c:188
Order compareTo(const Selector *self, const Selector *other)
Compares this Selector to other, ordering by specificity.
Definition: Selector.c:149
void enumerateSelection(const Selector *self, View *view, ViewEnumerator enumerator, ident data)
Selects from view and applies the given ViewEnumerator to all matched Views.
Definition: Selector.c:166
Array * parse(const char *rules)
Parses the null-terminated C string of Selector rules into an Array of Selectors.
Definition: Selector.c:274

◆ initWithRule()

static Selector * initWithRule ( Selector self,
const char *  rule 
)
static

Definition at line 188 of file Selector.c.

188 {
189
190 self = (Selector *) super(Object, self, init);
191 if (self) {
192
193 self->rule = strtrim(rule);
194 assert(self->rule);
195
196 self->sequences = $$(SelectorSequence, parse, self->rule);
197 assert(self->sequences->count);
198
199 self->specificity = specificity(self);
200 }
201
202 return self;
203}
static int specificity(const Selector *selector)
Definition: Selector.c:97
CollectionView * init(CollectionView *self, const SDL_Rect *frame)
Initializes this CollectionView with the specified frame and style.
char * rule
The rule, as provided by the user.
Definition: Selector.h:70

◆ isEqual()

static _Bool isEqual ( const Object *  self,
const Object *  other 
)
static
See also
Object::isEqual(const Object *, const Object *)

Definition at line 75 of file Selector.c.

75 {
76
77 if (super(Object, self, isEqual, other)) {
78 return true;
79 }
80
81 if (other && $(other, isKindOfClass, _Selector())) {
82
83 const Selector *this = (Selector *) self;
84 const Selector *that = (Selector *) other;
85
86 return strcmp(this->rule, that->rule) == 0;
87 }
88
89 return false;
90}
Class * _Selector(void)
The Selector archetype.
Definition: Selector.c:398

◆ matchesView()

static _Bool matchesView ( const Selector self,
const View view 
)
static

Definition at line 260 of file Selector.c.

260 {
261
262 assert(view);
263
264 return _matchesView(view, &(Match) {
265 .sequences = self->sequences,
266 .sequence = self->sequences->count - 1
267 });
268}
A context for View matching.
Definition: Selector.c:208

◆ parse()

static Array * parse ( const char *  rules)
static

Definition at line 274 of file Selector.c.

274 {
275
276 MutableArray *selectors = $$(MutableArray, arrayWithCapacity, 4);
277 assert(selectors);
278
279 if (rules) {
280
281 const char *c = rules;
282 while (*c) {
283 const size_t size = strcspn(c, ",");
284 if (size) {
285 char *rule = calloc(1, size + 1);
286 assert(rule);
287
288 strncpy(rule, c, size);
289
290 Selector *selector = $(alloc(Selector), initWithRule, rule);
291 assert(selector);
292
293 $(selectors, addObject, selector);
294
295 release(selector);
296 free(rule);
297 }
298 c += size;
299 c += strspn(c, ", \t\n");
300 }
301 }
302
303 return (Array *) selectors;
304}
SDL_Size size(const Image *self)
Definition: Image.c:181

◆ specificity()

static int specificity ( const Selector selector)
static
Returns
The specificity of the given Selector.

Definition at line 97 of file Selector.c.

97 {
98
99 int specificity = 0;
100
101 for (size_t i = 0; i < selector->sequences->count; i++) {
102 SelectorSequence *sequence = $(selector->sequences, objectAtIndex, i);
103
104 for (size_t j = 0; j < sequence->simpleSelectors->count; j++) {
105 SimpleSelector *simpleSelector = $(sequence->simpleSelectors, objectAtIndex, j);
106
107 switch (simpleSelector->type) {
109 specificity += 100;
110 break;
113 specificity += 10;
114 break;
116 specificity += 1;
117 Class *clazz = classForName(simpleSelector->pattern);
118 if (clazz) {
119 while (clazz) {
120 if (clazz == _View()) {
121 break;
122 }
123 specificity += 1;
124 clazz = clazz->def.superclass;
125 }
126 if (clazz != _View()) {
127 MVC_LogError("Class `%s` in Selector `%s` does not extend View\n",
128 simpleSelector->pattern, selector->rule);
129 }
130 } else {
131 MVC_LogWarn("Class `%s` in Selector `%s` not found\n",
132 simpleSelector->pattern, selector->rule);
133 }
134
135 break;
136 default:
137 break;
138 }
139 }
140 }
141
142 return specificity;
143}
#define MVC_LogWarn(fmt,...)
Definition: Log.h:52
#define MVC_LogError(fmt,...)
Definition: Log.h:55
@ SimpleSelectorTypePseudo
@ SimpleSelectorTypeId
@ SimpleSelectorTypeClass
@ SimpleSelectorTypeType
Array * simpleSelectors
The SimpleSelectors comprising this SelectorSequence.
The SimpleSelector type.
SimpleSelectorType type
The SimpleSelectorType.
char * pattern
The pattern, as provided by the user.
Class * _View(void)
The View archetype.
Definition: View.c:1769