ObjectivelyMVC 0.1.0
Object oriented MVC framework for OpenGL, SDL2 and GNU C
Stylesheet.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/Hash.h>
28
29#include "ObjectivelyMVC.h"
30
31#include "stylesheet.css.h"
32
33#define _Class _Stylesheet
34
35#pragma mark - Object
36
40static void dealloc(Object *self) {
41
42 Stylesheet *this = (Stylesheet *) self;
43
44 release(this->selectors);
45 release(this->styles);
46
47 super(Object, self, dealloc);
48}
49
53static int hash(const Object *self) {
54
55 Stylesheet *this = (Stylesheet *) self;
56
57 int hash = HASH_SEED;
58
59 hash = HashForObject(hash, this->selectors);
60 hash = HashForObject(hash, this->styles);
61
62 return hash;
63}
64
68static _Bool isEqual(const Object *self, const Object *other) {
69
70 if (super(Object, self, isEqual, other)) {
71 return true;
72 }
73
74 if (other && $(other, isKindOfClass, _Stylesheet())) {
75
76 const Stylesheet *this = (Stylesheet *) self;
77 const Stylesheet *that = (Stylesheet *) other;
78
79 if ($((Object *) this->selectors, isEqual, (Object *) that->selectors)) {
80 return $((Object *) this->styles, isEqual, (Object *) that->styles);
81 }
82 }
83
84 return false;
85}
86
87#pragma mark - Stylesheet
88
90
96 static Once once;
97
98 do_once(&once, {
99 _defaultStylesheet = $$(Stylesheet, stylesheetWithCharacters, (char *) stylesheet_css);
100 assert(_defaultStylesheet);
101 });
102
103 return _defaultStylesheet;
104}
105
106static ident selectorsReducer(const ident obj, ident accumulator, ident data) {
107
108 $((MutableArray *) accumulator, addObjectsFromArray, ((Style *) obj)->selectors);
109
110 return accumulator;
111}
112
116static Order selectorsComparator(const ident a, const ident b) {
117 return $((Selector *) a, compareTo, (Selector *) b);
118}
119
124static Stylesheet *initWithCharacters(Stylesheet *self, const char *chars) {
125
126 self = (Stylesheet *) super(Object, self, init);
127 if (self) {
128
129 self->styles = $$(Style, parse, chars);
130 assert(self->styles);
131
132 MutableArray *selectors = $$(MutableArray, array);
133 assert(selectors);
134
135 $(self->styles, reduce, selectorsReducer, selectors, NULL);
136
137 self->selectors = $((Array *) selectors, sortedArray, selectorsComparator);
138 assert(self->selectors);
139
140 release(selectors);
141 }
142
143 return self;
144}
145
150static Stylesheet *initWithData(Stylesheet *self, const Data *data) {
151
152 assert(data);
153
154 String *string = $$(String, stringWithData, data, STRING_ENCODING_UTF8);
155 assert(string);
156
157 self = $(self, initWithString, string);
158
159 release(string);
160 return self;
161}
162
167static Stylesheet *initWithResource(Stylesheet *self, const Resource *resource) {
168
169 assert(resource);
170
171 return $(self, initWithData, resource->data);
172}
173
178static Stylesheet *initWithResourceName(Stylesheet *self, const char *name) {
179
180 assert(name);
181
182 Resource *resource = $$(Resource, resourceWithName, name);
183 assert(resource);
184
185 self = $(self, initWithResource, resource);
186
187 release(resource);
188 return self;
189}
190
195static Stylesheet *initWithString(Stylesheet *self, const String *string) {
196
197 assert(string);
198
199 return $(self, initWithCharacters, string->chars);
200}
201
206static Stylesheet *stylesheetWithCharacters(const char *chars) {
207 return $(alloc(Stylesheet), initWithCharacters, chars);
208}
209
214static Stylesheet *stylesheetWithData(const Data *data) {
215 return $(alloc(Stylesheet), initWithData, data);
216}
217
222static Stylesheet *stylesheetWithResource(const Resource *resource) {
223 return $(alloc(Stylesheet), initWithResource, resource);
224}
225
230static Stylesheet *stylesheetWithResourceName(const char *name) {
231 return $(alloc(Stylesheet), initWithResourceName, name);
232}
233
238static Stylesheet *stylesheetWithString(const String *string) {
239 return $(alloc(Stylesheet), initWithString, string);
240}
241
242#pragma mark - Class lifecycle
243
247static void initialize(Class *clazz) {
248
249 ((ObjectInterface *) clazz->interface)->dealloc = dealloc;
250 ((ObjectInterface *) clazz->interface)->hash = hash;
251 ((ObjectInterface *) clazz->interface)->isEqual = isEqual;
252
253 ((StylesheetInterface *) clazz->interface)->defaultStylesheet = defaultStylesheet;
254 ((StylesheetInterface *) clazz->interface)->initWithCharacters = initWithCharacters;
255 ((StylesheetInterface *) clazz->interface)->initWithData = initWithData;
256 ((StylesheetInterface *) clazz->interface)->initWithResource = initWithResource;
257 ((StylesheetInterface *) clazz->interface)->initWithResourceName = initWithResourceName;
258 ((StylesheetInterface *) clazz->interface)->initWithString = initWithString;
259 ((StylesheetInterface *) clazz->interface)->stylesheetWithCharacters = stylesheetWithCharacters;
260 ((StylesheetInterface *) clazz->interface)->stylesheetWithData = stylesheetWithData;
261 ((StylesheetInterface *) clazz->interface)->stylesheetWithResource = stylesheetWithResource;
262 ((StylesheetInterface *) clazz->interface)->stylesheetWithResourceName = stylesheetWithResourceName;
263 ((StylesheetInterface *) clazz->interface)->stylesheetWithString = stylesheetWithString;
264}
265
269static void destroy(Class *clazz) {
270 release(_defaultStylesheet);
271}
272
277Class *_Stylesheet(void) {
278 static Class *clazz;
279 static Once once;
280
281 do_once(&once, {
282 clazz = _initialize(&(const ClassDef) {
283 .name = "Stylesheet",
284 .superclass = _Object(),
285 .instanceSize = sizeof(Stylesheet),
286 .interfaceOffset = offsetof(Stylesheet, interface),
287 .interfaceSize = sizeof(StylesheetInterface),
289 .destroy = destroy,
290 });
291 });
292
293 return clazz;
294}
295
296#undef _Class
ObjectivelyMVC: Object oriented MVC framework for OpenGL, SDL2 and GNU C.
static void destroy(Class *clazz)
Definition: Stylesheet.c:269
static Stylesheet * stylesheetWithData(const Data *data)
Definition: Stylesheet.c:214
static ident selectorsReducer(const ident obj, ident accumulator, ident data)
Definition: Stylesheet.c:106
static _Bool isEqual(const Object *self, const Object *other)
Definition: Stylesheet.c:68
static void dealloc(Object *self)
Definition: Stylesheet.c:40
static Stylesheet * _defaultStylesheet
Definition: Stylesheet.c:89
static void initialize(Class *clazz)
Definition: Stylesheet.c:247
static int hash(const Object *self)
Definition: Stylesheet.c:53
static Order selectorsComparator(const ident a, const ident b)
Comparator for Selector sorting.
Definition: Stylesheet.c:116
CollectionView * init(CollectionView *self, const SDL_Rect *frame)
Initializes this CollectionView with the specified frame and style.
Font * initWithData(Font *self, Data *data, int size, int index)
Data * data
The raw font data.
Definition: Font.h:79
Image * initWithResourceName(Image *self, const char *name)
Initializes this Image, loading the Resource by the given name.
Definition: Image.c:142
Image * initWithResource(Image *self, const Resource *resource)
Initializes this Image with the specified Resource.
Definition: Image.c:126
Selectors are comprised of one or more SelectorSequences.
Definition: Selector.h:49
Order compareTo(const Selector *self, const Selector *other)
Compares this Selector to other, ordering by specificity.
Definition: Selector.c:149
Array * parse(const char *rules)
Parses the null-terminated C string of Selector rules into an Array of Selectors.
Definition: Selector.c:274
The Style type.
Definition: Style.h:43
Stylesheets are comprised of Selectors and Styles.
Definition: Stylesheet.h:44
Stylesheet * stylesheetWithCharacters(const char *chars)
Instantiates a new Stylesheet with the given CSS definitions.
Definition: Stylesheet.c:206
Stylesheet * initWithData(Stylesheet *self, const Data *data)
Initializes this Stylesheet with the CSS definitions in data.
Definition: Stylesheet.c:150
Array * styles
The Styles, keyed by Selector.
Definition: Stylesheet.h:65
Stylesheet * stylesheetWithString(const String *string)
Instantiates a new Stylesheet with the given CSS String.
Definition: Stylesheet.c:238
Stylesheet * defaultStylesheet(void)
Definition: Stylesheet.c:95
Stylesheet * stylesheetWithResource(const Resource *resource)
Instantiates a new Stylesheet with the given CSS Resource.
Definition: Stylesheet.c:222
Class * _Stylesheet(void)
The Stylesheet archetype.
Definition: Stylesheet.c:277
Stylesheet * initWithCharacters(Stylesheet *self, const char *chars)
Initializes this Stylesheet with the given CSS definitions.
Definition: Stylesheet.c:124
Array * selectors
The Selectors, ordered by specificity.
Definition: Stylesheet.h:60
Stylesheet * initWithString(Stylesheet *self, const String *string)
Initializes this Stylesheet with the CSS definitions in string.
Definition: Stylesheet.c:195
Stylesheet * stylesheetWithResourceName(const char *name)
Instantiates a new Stylesheet with the CSS Resource by the specified name.
Definition: Stylesheet.c:230