summaryrefslogtreecommitdiff
path: root/src/lib/emotion/emotion_modules.c
diff options
context:
space:
mode:
authorGustavo Sverzut Barbieri <barbieri@gmail.com>2013-01-11 03:06:42 +0000
committerGustavo Sverzut Barbieri <barbieri@gmail.com>2013-01-11 03:06:42 +0000
commit356d4f733cd51ebcc95ad436044aa1fdd4aef6df (patch)
tree68104f9cd4bf1c7edcb6fa096389a688b0f6e7b5 /src/lib/emotion/emotion_modules.c
parent4c64334b9d801f85dd19a6122db75cc3a1ecab6f (diff)
efl/emotion: rework module infra, better integration with 'generic'.
Change the module infra and allow one to register using the description structure itself, saves some work. Replace module_open and module_close with add() and del(), that are more descriptive. Move stuff to init/shutdown where it was a better fit. Since add() now receives the first parameter being the owning structure we can create one structure per generic player and they will merge transparently with other modules, then we can use a simple algorithm that considers the plugin priority. ALL DYNAMIC! Future work could be done to load the plugin priority specified by user from configuration file. But this is not in my plans right now. SVN revision: 82602
Diffstat (limited to 'src/lib/emotion/emotion_modules.c')
-rw-r--r--src/lib/emotion/emotion_modules.c219
1 files changed, 151 insertions, 68 deletions
diff --git a/src/lib/emotion/emotion_modules.c b/src/lib/emotion/emotion_modules.c
index 3e8a18a320..95ac2b3c91 100644
--- a/src/lib/emotion/emotion_modules.c
+++ b/src/lib/emotion/emotion_modules.c
@@ -17,10 +17,38 @@ Eina_Bool generic_module_init(void);
17void generic_module_shutdown(void); 17void generic_module_shutdown(void);
18#endif 18#endif
19 19
20static Eina_Hash *_emotion_backends = NULL; 20typedef struct _Emotion_Engine_Registry_Entry
21{
22 const Emotion_Engine *engine;
23 int priority;
24} Emotion_Engine_Registry_Entry;
25
26static Eina_List *_emotion_engine_registry = NULL;
21static Eina_Array *_emotion_modules = NULL; 27static Eina_Array *_emotion_modules = NULL;
22 28
23static void 29static void
30_emotion_engine_registry_entry_free(Emotion_Engine_Registry_Entry *re)
31{
32 free(re);
33}
34
35static int
36_emotion_engine_registry_entry_cmp(const void *pa, const void *pb)
37{
38 const Emotion_Engine_Registry_Entry *a = pa, *b = pb;
39 int r = a->priority - b->priority;
40
41 if (r == 0)
42 r = a->engine->priority - b->engine->priority;
43
44 if (r == 0)
45 /* guarantee some order to ease debug */
46 r = strcmp(a->engine->name, b->engine->name);
47
48 return r;
49}
50
51static void
24_emotion_modules_load(void) 52_emotion_modules_load(void)
25{ 53{
26 char buf[PATH_MAX]; 54 char buf[PATH_MAX];
@@ -80,9 +108,6 @@ emotion_modules_init(void)
80{ 108{
81 int static_modules = 0; 109 int static_modules = 0;
82 110
83 _emotion_backends = eina_hash_string_small_new(free);
84 EINA_SAFETY_ON_NULL_RETURN_VAL(_emotion_backends, EINA_FALSE);
85
86 _emotion_modules_load(); 111 _emotion_modules_load();
87 112
88 /* Init static module */ 113 /* Init static module */
@@ -101,12 +126,20 @@ emotion_modules_init(void)
101 else if (_emotion_modules) 126 else if (_emotion_modules)
102 eina_module_list_load(_emotion_modules); 127 eina_module_list_load(_emotion_modules);
103 128
129 if (!_emotion_engine_registry)
130 ERR("Couldn't find any emotion engine.");
131
104 return EINA_TRUE; 132 return EINA_TRUE;
105} 133}
106 134
107void 135void
108emotion_modules_shutdown(void) 136emotion_modules_shutdown(void)
109{ 137{
138 Emotion_Engine_Registry_Entry *re;
139
140 EINA_LIST_FREE(_emotion_engine_registry, re)
141 _emotion_engine_registry_entry_free(re);
142
110#ifdef EMOTION_STATIC_BUILD_XINE 143#ifdef EMOTION_STATIC_BUILD_XINE
111 xine_module_shutdown(); 144 xine_module_shutdown();
112#endif 145#endif
@@ -123,39 +156,74 @@ emotion_modules_shutdown(void)
123 eina_array_free(_emotion_modules); 156 eina_array_free(_emotion_modules);
124 _emotion_modules = NULL; 157 _emotion_modules = NULL;
125 } 158 }
126
127 eina_hash_free(_emotion_backends);
128 _emotion_backends = NULL;
129} 159}
130 160
131EAPI Eina_Bool 161EAPI Eina_Bool
132_emotion_module_register(const char *name, Emotion_Module_Open mod_open, Emotion_Module_Close mod_close) 162_emotion_module_register(const Emotion_Engine *api)
133{ 163{
134 Eina_Emotion_Plugins *plugin; 164 Emotion_Engine_Registry_Entry *re;
165
166 EINA_SAFETY_ON_NULL_RETURN_VAL(api, EINA_FALSE);
167
168 if (api->version != EMOTION_ENGINE_API_VERSION)
169 {
170 ERR("Module '%p' uses api version=%u while %u was expected",
171 api, api->version, EMOTION_ENGINE_API_VERSION);
172 return EINA_FALSE;
173 }
174
175 EINA_SAFETY_ON_NULL_RETURN_VAL(api->name, EINA_FALSE);
176
177 INF("register name=%s, version=%u, priority=%d, api=%p",
178 api->name, api->version, api->priority, api);
179
180 re = calloc(1, sizeof(Emotion_Engine_Registry_Entry));
181 EINA_SAFETY_ON_NULL_RETURN_VAL(re, EINA_FALSE);
135 182
136 plugin = malloc(sizeof (Eina_Emotion_Plugins)); 183 re->engine = api;
137 EINA_SAFETY_ON_NULL_RETURN_VAL(plugin, EINA_FALSE); 184 re->priority = api->priority; // TODO: use user-priority from file as weel.
138 185
139 plugin->open = mod_open; 186 _emotion_engine_registry = eina_list_sorted_insert
140 plugin->close = mod_close; 187 (_emotion_engine_registry, _emotion_engine_registry_entry_cmp, re);
141 188
142 INF("register module=%s, open=%p, close=%p", name, mod_open, mod_close); 189 return EINA_TRUE;
143 return eina_hash_add(_emotion_backends, name, plugin);
144} 190}
145 191
146EAPI Eina_Bool 192EAPI Eina_Bool
147_emotion_module_unregister(const char *name) 193_emotion_module_unregister(const Emotion_Engine *api)
148{ 194{
149 INF("unregister module=%s", name); 195 Eina_List *n;
150 return eina_hash_del_by_key(_emotion_backends, name); 196 Emotion_Engine_Registry_Entry *re;
197
198 EINA_SAFETY_ON_NULL_RETURN_VAL(api, EINA_FALSE);
199 if (api->version != EMOTION_ENGINE_API_VERSION)
200 {
201 ERR("Module '%p' uses api version=%u while %u was expected",
202 api, api->version, EMOTION_ENGINE_API_VERSION);
203 return EINA_FALSE;
204 }
205
206 INF("unregister name=%s, api=%p", api->name, api);
207
208 EINA_LIST_FOREACH(_emotion_engine_registry, n, re)
209 {
210 if (re->engine == api)
211 {
212 _emotion_engine_registry_entry_free(re);
213 _emotion_engine_registry = eina_list_remove_list
214 (_emotion_engine_registry, n);
215 return EINA_TRUE;
216 }
217 }
218
219 ERR("module not registered name=%s, api=%p", api->name, api);
220 return EINA_FALSE;
151} 221}
152 222
153struct _Emotion_Engine_Instance 223struct _Emotion_Engine_Instance
154{ 224{
155 Eina_Emotion_Plugins *plugin; 225 const Emotion_Engine *api;
156 Emotion_Video_Module *api;
157 Evas_Object *obj; 226 Evas_Object *obj;
158 char *name;
159 void *data; 227 void *data;
160}; 228};
161 229
@@ -192,66 +260,81 @@ struct _Emotion_Engine_Instance
192 while (0) 260 while (0)
193 261
194 262
195static const char *_backend_priority[] = { 263static const Emotion_Engine *
196 "gstreamer", 264_emotion_engine_registry_find(const char *name)
197 "xine", 265{
198 "generic" 266 const Eina_List *n;
199}; 267 const Emotion_Engine_Registry_Entry *re;
268 EINA_LIST_FOREACH(_emotion_engine_registry, n, re)
269 {
270 if (strcmp(re->engine->name, name) == 0)
271 return re->engine;
272 }
273 return NULL;
274}
275
276static Emotion_Engine_Instance *
277_emotion_engine_instance_new(const Emotion_Engine *engine, Evas_Object *obj, void *data)
278{
279 Emotion_Engine_Instance *inst = calloc(1, sizeof(Emotion_Engine_Instance));
280 EINA_SAFETY_ON_NULL_GOTO(inst, error);
281 inst->api = engine;
282 inst->obj = obj;
283 inst->data = data;
284 return inst;
285
286 error:
287 engine->del(data);
288 return NULL;
289}
200 290
201Emotion_Engine_Instance * 291Emotion_Engine_Instance *
202emotion_engine_instance_new(const char *name, Evas_Object *obj, Emotion_Module_Options *opts) 292emotion_engine_instance_new(const char *name, Evas_Object *obj, Emotion_Module_Options *opts)
203{ 293{
204 // TODO: rewrite 294 const Eina_List *n;
205 Eina_Emotion_Plugins *plugin; 295 const Emotion_Engine_Registry_Entry *re;
206 unsigned int i = 0; 296 const Emotion_Engine *engine;
207 Emotion_Video_Module *mod = NULL; 297 void *data;
208 void *data = NULL;
209
210 if (!_emotion_backends)
211 {
212 ERR("No backend loaded");
213 return NULL;
214 }
215 298
216 if (!name && getenv("EMOTION_ENGINE")) 299 if ((!name) && getenv("EMOTION_ENGINE"))
217 { 300 {
218 name = getenv("EMOTION_ENGINE"); 301 name = getenv("EMOTION_ENGINE");
219 DBG("using EMOTION_ENGINE=%s", name); 302 DBG("using EMOTION_ENGINE=%s", name);
220 } 303 }
221 304
222 /* FIXME: Always look for a working backend. */ 305 if (name)
223 retry:
224 if (!name || i > 0)
225 name = _backend_priority[i++];
226
227 plugin = eina_hash_find(_emotion_backends, name);
228 DBG("try engine=%s, plugin=%p", name, plugin);
229 if (!plugin)
230 { 306 {
231 if (i != 0 && i < (sizeof (_backend_priority) / sizeof (char*))) 307 engine = _emotion_engine_registry_find(name);
232 goto retry; 308 if (!engine)
309 ERR("Couldn't find requested engine: %s. Try fallback", name);
310 else
311 {
312 data = engine->add(engine, obj, opts);
313 if (data)
314 {
315 INF("Using requested engine %s, data=%p", name, data);
316 return _emotion_engine_instance_new(engine, obj, data);
317 }
233 318
234 ERR("No backend loaded"); 319 ERR("Requested engine '%s' could not be used. Try fallback", name);
235 return NULL; 320 }
236 } 321 }
237 322
238 if (plugin->open(obj, (const Emotion_Video_Module **) &mod, &data, opts)) 323 EINA_LIST_FOREACH(_emotion_engine_registry, n, re)
239 { 324 {
240 Emotion_Engine_Instance *inst = calloc(1, sizeof(Emotion_Engine_Instance)); 325 engine = re->engine;
241 INF("opened %s, mod=%p, video=%p", name, mod, data); 326 DBG("Trying engine %s, priority=%d (%d)",
242 inst->plugin = plugin; 327 engine->name, re->priority, engine->priority);
243 inst->api = mod;
244 inst->obj = obj;
245 inst->data = data;
246 inst->name = strdup(name);
247 return inst;
248 }
249 328
250 if (i != 0 && i < (sizeof (_backend_priority) / sizeof (char*))) 329 data = engine->add(engine, obj, opts);
251 goto retry; 330 if (data)
252 331 {
253 ERR("Unable to load module: %s", name); 332 INF("Using fallback engine %s, data=%p", engine->name, data);
333 return _emotion_engine_instance_new(engine, obj, data);
334 }
335 }
254 336
337 ERR("No engine worked");
255 return NULL; 338 return NULL;
256} 339}
257 340
@@ -259,7 +342,7 @@ void
259emotion_engine_instance_del(Emotion_Engine_Instance *inst) 342emotion_engine_instance_del(Emotion_Engine_Instance *inst)
260{ 343{
261 EINA_SAFETY_ON_NULL_RETURN(inst); 344 EINA_SAFETY_ON_NULL_RETURN(inst);
262 inst->plugin->close(inst->api, inst->data); // TODO: weird api 345 inst->api->del(inst->data);
263} 346}
264 347
265Eina_Bool 348Eina_Bool
@@ -268,7 +351,7 @@ emotion_engine_instance_name_equal(const Emotion_Engine_Instance *inst, const ch
268 /* these are valid, no safety macros here */ 351 /* these are valid, no safety macros here */
269 if (!name) return EINA_FALSE; 352 if (!name) return EINA_FALSE;
270 if (!inst) return EINA_FALSE; 353 if (!inst) return EINA_FALSE;
271 return strcmp(name, inst->name) == 0; 354 return strcmp(name, inst->api->name) == 0;
272} 355}
273 356
274void * 357void *
@@ -278,11 +361,11 @@ emotion_engine_instance_data_get(const Emotion_Engine_Instance *inst)
278 return inst->data; 361 return inst->data;
279} 362}
280 363
281unsigned char 364Eina_Bool
282emotion_engine_instance_file_open(Emotion_Engine_Instance *inst, const char *file) 365emotion_engine_instance_file_open(Emotion_Engine_Instance *inst, const char *file)
283{ 366{
284 EMOTION_ENGINE_INSTANCE_CHECK(inst, file_open, EINA_FALSE); 367 EMOTION_ENGINE_INSTANCE_CHECK(inst, file_open, EINA_FALSE);
285 return inst->api->file_open(file, inst->obj, inst->data); // TODO: weird api 368 return inst->api->file_open(inst->data, file);
286} 369}
287 370
288void 371void