ObjectivelyMVC 0.1.0
Object oriented MVC framework for OpenGL, SDL2 and GNU C
SelectorSequence.c
Go to the documentation of this file.
1/*
2 * ObjectivelyMVC: Object oriented MVC framework for OpenGL, SDL2 and GNU C.
3 * Copyright (C) 2014 Jay Dolan <jay@jaydolan.com>
4 *
5 * This software is provided 'as-is', without any express or implied
6 * warranty. In no event will the authors be held liable for any damages
7 * arising from the use of this software.
8 *
9 * Permission is granted to anyone to use this software for any purpose,
10 * including commercial applications, and to alter it and redistribute it
11 * freely, subject to the following restrictions:
12 *
13 * 1. The origin of this software must not be misrepresented; you must not
14 * claim that you wrote the original software. If you use this software
15 * in a product, an acknowledgment in the product documentation would be
16 * appreciated but is not required.
17 *
18 * 2. Altered source versions must be plainly marked as such, and must not be
19 * misrepresented as being the original software.
20 *
21 * 3. This notice may not be removed or altered from any source distribution.
22 */
23
24#include <assert.h>
25#include <string.h>
26
27#include <Objectively/MutableArray.h>
28
29#include "SelectorSequence.h"
30#include "View.h"
31
32#define _Class _SelectorSequence
33
34#pragma mark - Object
35
39static void dealloc(Object *self) {
40
41 SelectorSequence *this = (SelectorSequence *) self;
42
43 free(this->sequence);
44 release(this->simpleSelectors);
45
46 super(Object, self, dealloc);
47}
48
52static String *description(const Object *self) {
53
54 const SelectorSequence *this = (SelectorSequence *) self;
55
56 return str(this->sequence);
57}
58
59#pragma mark - SelectorSequence
60
65static SelectorSequence *initWithSequence(SelectorSequence *self, const char *sequence) {
66
67 self = (SelectorSequence *) super(Object, self, init);
68 if (self) {
69
70 self->sequence = strtrim(sequence);
71 assert(self->sequence);
72
73 assert(strlen(self->sequence));
74
75 self->simpleSelectors = $$(SimpleSelector, parse, self->sequence);
76 assert(self->simpleSelectors->count);
77 }
78
79 return self;
80}
81
86static _Bool matchesView(const SelectorSequence *self, const View *view) {
87
88 for (size_t i = 0; i < self->simpleSelectors->count; i++) {
89 const SimpleSelector *simpleSelector = $(self->simpleSelectors, objectAtIndex, i);
90 if ($(view, matchesSelector, simpleSelector) == false) {
91 return false;
92 }
93 }
94
95 return true;
96}
97
102
104
105 while (isspace(*c)) {
106 combinator = SequenceCombinatorDescendent;
107 c++;
108 }
109
110 switch (*c) {
111 case '>':
113 case '~':
115 case '+':
117 case '\0':
119 default:
120 break;
121 }
122
123 return combinator;
124}
125
130static Array *parse(const char *rule) {
131
132 assert(rule);
133
134 MutableArray *selectorSequences = $$(MutableArray, arrayWithCapacity, 8);
135 assert(selectorSequences);
136
138
139 const char *c = rule;
140 while (*c) {
141 const size_t size = strcspn(c, " \n\t>+~");
142 if (size) {
143 char *sequence = calloc(1, size + 1);
144 assert(sequence);
145
146 strncpy(sequence, c, size);
147
148 SelectorSequence *selectorSequence = $(alloc(SelectorSequence), initWithSequence, sequence);
149 assert(selectorSequence);
150
151 selectorSequence->right = sequenceCombinator(c + size);
152 assert(selectorSequence->right);
153
154 selectorSequence->left = left;
155 left = selectorSequence->right;
156
157 $(selectorSequences, addObject, selectorSequence);
158
159 release(selectorSequence);
160 free(sequence);
161 }
162
163 c += size;
164 c += strspn(c, " \n\t>+~");
165 }
166
167 return (Array *) selectorSequences;
168}
169
170#pragma mark - Class lifecycle
171
175static void initialize(Class *clazz) {
176
177 ((ObjectInterface *) clazz->interface)->dealloc = dealloc;
178 ((ObjectInterface *) clazz->interface)->description = description;
179
180 ((SelectorSequenceInterface *) clazz->interface)->initWithSequence = initWithSequence;
181 ((SelectorSequenceInterface *) clazz->interface)->matchesView = matchesView;
182 ((SelectorSequenceInterface *) clazz->interface)->parse = parse;
183}
184
189Class *_SelectorSequence(void) {
190 static Class *clazz;
191 static Once once;
192
193 do_once(&once, {
194 clazz = _initialize(&(const ClassDef) {
195 .name = "SelectorSequence",
196 .superclass = _Object(),
197 .instanceSize = sizeof(SelectorSequence),
198 .interfaceOffset = offsetof(SelectorSequence, interface),
199 .interfaceSize = sizeof(SelectorSequenceInterface),
201 });
202 });
203
204 return clazz;
205}
206
207#undef _Class
static String * description(const Object *self)
static SequenceCombinator sequenceCombinator(const char *c)
static void dealloc(Object *self)
static void initialize(Class *clazz)
The SeletorSequence type.
SequenceCombinator
Combinators are operators for chaining SelectorSequences.
@ SequenceCombinatorTerminal
@ SequenceCombinatorAdjacent
@ SequenceCombinatorNone
@ SequenceCombinatorChild
@ SequenceCombinatorDescendent
@ SequenceCombinatorSibling
Views are the fundamental building blocks of ObjectivelyMVC user interfaces.
CollectionView * init(CollectionView *self, const SDL_Rect *frame)
Initializes this CollectionView with the specified frame and style.
SDL_Size size(const Image *self)
Definition: Image.c:181
_Bool matchesView(const Selector *self, View *view)
Array * parse(const char *rules)
Parses the null-terminated C string of Selector rules into an Array of Selectors.
Definition: Selector.c:274
SelectorSequences are comprised of one or more SimpleSelectors.
_Bool matchesView(const SelectorSequence *self, const View *view)
SequenceCombinator right
SelectorSequence * initWithSequence(SelectorSequence *self, const char *sequence)
Initializes this SelectorSequence with the given sequence.
SequenceCombinator left
The combinators.
char * sequence
The sequence, as provided by the user.
Class * _SelectorSequence(void)
The SelectorSequence archetype.
Array * simpleSelectors
The SimpleSelectors comprising this SelectorSequence.
The SimpleSelector type.
Views are the fundamental building blocks of ObjectivelyMVC user interfaces.
Definition: View.h:133
_Bool matchesSelector(const View *self, const SimpleSelector *simpleSelector)