forked from enlightenment/efl
ethumb: make exists client API async.
Ethumb_Client now use Ecore_Thread with this patch. TODO: * cache exists requests (client side). * cache generate requests (server side). SVN revision: 58977
This commit is contained in:
parent
a288cd7af1
commit
bcef93caba
|
@ -157,12 +157,38 @@ _finished_thumb(void *data __UNUSED__, Ethumb_Client *client __UNUSED__, int id
|
|||
}
|
||||
|
||||
static void
|
||||
_connected(void *data, Ethumb_Client *c, Eina_Bool success)
|
||||
_exists(Ethumb_Client *c, __UNUSED__ Ethumb_Exists *thread, Eina_Bool exists, void *data)
|
||||
{
|
||||
struct options *opts = data;
|
||||
const char *thumb_path, *thumb_key;
|
||||
long id;
|
||||
|
||||
if (exists)
|
||||
{
|
||||
ethumb_client_thumb_path_get(c, &thumb_path, &thumb_key);
|
||||
_thumb_report
|
||||
("EXISTS", opts->src_path, opts->src_key, thumb_path, thumb_key);
|
||||
ecore_main_loop_quit();
|
||||
return;
|
||||
}
|
||||
|
||||
id = ethumb_client_generate(c, _finished_thumb, NULL, NULL);
|
||||
if (id < 0)
|
||||
{
|
||||
fputs("ERROR: could not request thumbnail to be generated.\n", stderr);
|
||||
ecore_main_loop_quit();
|
||||
return;
|
||||
}
|
||||
printf("request id=%ld, file='%s', key='%s'\n",
|
||||
id, opts->src_path, opts->src_key ? opts->src_key : "");
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
_connected(void *data, Ethumb_Client *c, Eina_Bool success)
|
||||
{
|
||||
struct options *opts = data;
|
||||
|
||||
if (!success)
|
||||
{
|
||||
fputs("ERROR: could not connect to DBus server.\n", stderr);
|
||||
|
@ -196,24 +222,7 @@ _connected(void *data, Ethumb_Client *c, Eina_Bool success)
|
|||
}
|
||||
|
||||
ethumb_client_thumb_path_set(c, opts->thumb_path, opts->thumb_key);
|
||||
ethumb_client_thumb_path_get(c, &thumb_path, &thumb_key);
|
||||
if (ethumb_client_thumb_exists(c))
|
||||
{
|
||||
_thumb_report
|
||||
("EXISTS", opts->src_path, opts->src_key, thumb_path, thumb_key);
|
||||
ecore_main_loop_quit();
|
||||
return;
|
||||
}
|
||||
|
||||
id = ethumb_client_generate(c, _finished_thumb, NULL, NULL);
|
||||
if (id < 0)
|
||||
{
|
||||
fputs("ERROR: could not request thumbnail to be generated.\n", stderr);
|
||||
ecore_main_loop_quit();
|
||||
return;
|
||||
}
|
||||
printf("request id=%ld, file='%s', key='%s'\n",
|
||||
id, opts->src_path, opts->src_key ? opts->src_key : "");
|
||||
ethumb_client_thumb_exists(c, _exists, opts);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -244,6 +244,7 @@ ethumb_new(void)
|
|||
if (!e)
|
||||
{
|
||||
ERR("could not create ecore evas buffer");
|
||||
free(ethumb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -259,8 +260,8 @@ ethumb_new(void)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
sub_ee = evas_object_data_get(o, "Ecore_Evas");
|
||||
sub_e = ecore_evas_get(sub_ee);
|
||||
sub_ee = ecore_evas_object_ecore_evas_get(o);
|
||||
sub_e = ecore_evas_object_evas_get(o);
|
||||
|
||||
evas_image_cache_set(sub_e, 0);
|
||||
evas_font_cache_set(sub_e, 0);
|
||||
|
@ -678,12 +679,12 @@ ethumb_video_start_get(const Ethumb *e)
|
|||
}
|
||||
|
||||
EAPI void
|
||||
ethumb_video_time_set(Ethumb *e, float time)
|
||||
ethumb_video_time_set(Ethumb *e, float t)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN(e);
|
||||
|
||||
DBG("ethumb=%p, video_start=%f", e, time);
|
||||
e->video.time = time;
|
||||
DBG("ethumb=%p, video_start=%f", e, t);
|
||||
e->video.time = t;
|
||||
}
|
||||
|
||||
EAPI float
|
||||
|
@ -1550,3 +1551,109 @@ ethumb_ecore_evas_get(const Ethumb *e)
|
|||
|
||||
return e->sub_ee;
|
||||
}
|
||||
|
||||
Ethumb *
|
||||
ethumb_dup(const Ethumb *e)
|
||||
{
|
||||
Ecore_Evas *ee;
|
||||
Ecore_Evas *sub_ee;
|
||||
Evas *ev;
|
||||
Evas *sub_ev;
|
||||
Evas_Object *o;
|
||||
Evas_Object *img;
|
||||
Ethumb *r;
|
||||
|
||||
r = malloc(sizeof (Ethumb));
|
||||
if (!r) return NULL;
|
||||
|
||||
memcpy(r, e, sizeof (Ethumb));
|
||||
|
||||
r->thumb_dir = eina_stringshare_ref(e->thumb_dir);
|
||||
r->category = eina_stringshare_ref(e->category);
|
||||
r->src_path = eina_stringshare_ref(e->src_path);
|
||||
r->src_key = eina_stringshare_ref(e->src_key);
|
||||
r->thumb_path = eina_stringshare_ref(e->thumb_path);
|
||||
r->thumb_key = eina_stringshare_ref(e->thumb_key);
|
||||
|
||||
ee = ecore_evas_buffer_new(1, 1);
|
||||
ev = ecore_evas_get(ee);
|
||||
if (!ev)
|
||||
{
|
||||
ERR("could not create ecore evas buffer");
|
||||
free(r);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
evas_image_cache_set(ev, 0);
|
||||
evas_font_cache_set(ev, 0);
|
||||
|
||||
o = ecore_evas_object_image_new(ee);
|
||||
if (!o)
|
||||
{
|
||||
ERR("could not create sub ecore evas buffer");
|
||||
ecore_evas_free(ee);
|
||||
free(r);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sub_ee = ecore_evas_object_ecore_evas_get(o);
|
||||
sub_ev = ecore_evas_object_evas_get(o);
|
||||
|
||||
evas_image_cache_set(sub_ev, 0);
|
||||
evas_font_cache_set(sub_ev, 0);
|
||||
|
||||
img = evas_object_image_add(sub_ev);
|
||||
if (!img)
|
||||
{
|
||||
ERR("could not create source objects.");
|
||||
ecore_evas_free(ee);
|
||||
free(r);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
r->ee = ee;
|
||||
r->sub_ee = sub_ee;
|
||||
r->e = ev;
|
||||
r->sub_e = sub_ev;
|
||||
r->o = o;
|
||||
r->img = img;
|
||||
|
||||
r->frame = NULL;
|
||||
r->finished_idler = NULL;
|
||||
r->finished_cb = NULL;
|
||||
r->cb_data = NULL;
|
||||
r->cb_data_free = NULL;
|
||||
r->cb_result = 0;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#define CHECK_DELTA(Param) \
|
||||
if (e1->Param != e2->Param) \
|
||||
return EINA_TRUE;
|
||||
|
||||
Eina_Bool
|
||||
ethumb_cmp(const Ethumb *e1, const Ethumb *e2)
|
||||
{
|
||||
CHECK_DELTA(thumb_dir);
|
||||
CHECK_DELTA(category);
|
||||
CHECK_DELTA(tw);
|
||||
CHECK_DELTA(th);
|
||||
CHECK_DELTA(format);
|
||||
CHECK_DELTA(aspect);
|
||||
CHECK_DELTA(orientation);
|
||||
CHECK_DELTA(crop_x);
|
||||
CHECK_DELTA(crop_y);
|
||||
CHECK_DELTA(quality);
|
||||
CHECK_DELTA(compress);
|
||||
CHECK_DELTA(rw);
|
||||
CHECK_DELTA(rh);
|
||||
CHECK_DELTA(video.start);
|
||||
CHECK_DELTA(video.time);
|
||||
CHECK_DELTA(video.interval);
|
||||
CHECK_DELTA(video.ntimes);
|
||||
CHECK_DELTA(video.fps);
|
||||
CHECK_DELTA(document.page);
|
||||
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
|
|
@ -183,7 +183,11 @@ EAPI void ethumb_file_free(Ethumb *e) EINA_ARG_NONNULL(1);
|
|||
|
||||
EAPI Eina_Bool ethumb_generate(Ethumb *e, Ethumb_Generate_Cb finished_cb, const void *data, Eina_Free_Cb free_data) EINA_ARG_NONNULL(1, 2);
|
||||
EAPI Eina_Bool ethumb_exists(Ethumb *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_PURE;
|
||||
/**
|
||||
|
||||
EAPI Ethumb *ethumb_dup(const Ethumb *e) EINA_ARG_NONNULL(1);
|
||||
EAPI Eina_Bool ethumb_cmp(const Ethumb *e1, const Ethumb *e2) EINA_ARG_NONNULL(1, 2) EINA_WARN_UNUSED_RESULT EINA_PURE;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
|
|
@ -78,6 +78,7 @@
|
|||
#include <eina_safety_checks.h>
|
||||
#include <E_DBus.h>
|
||||
#include <Ethumb.h>
|
||||
#include <Ecore.h>
|
||||
|
||||
#include "Ethumb_Client.h"
|
||||
|
||||
|
@ -123,9 +124,12 @@ struct _Ethumb_Client
|
|||
} die;
|
||||
const char *object_path;
|
||||
|
||||
int refcount;
|
||||
|
||||
Eina_Bool ethumb_dirty : 1;
|
||||
Eina_Bool connected : 1;
|
||||
Eina_Bool server_started : 1;
|
||||
Eina_Bool delete_me : 1;
|
||||
};
|
||||
|
||||
struct _ethumb_pending_add
|
||||
|
@ -164,6 +168,22 @@ struct _ethumb_pending_gen
|
|||
Eina_Free_Cb free_data;
|
||||
};
|
||||
|
||||
typedef struct _Ethumb_Async_Exists Ethumb_Async_Exists;
|
||||
|
||||
struct _Ethumb_Async_Exists
|
||||
{
|
||||
Ethumb *dup;
|
||||
Ethumb_Client *source;
|
||||
|
||||
Ethumb_Client_Thumb_Exists_Cb exists_cb;
|
||||
const void *data;
|
||||
|
||||
Ecore_Thread *thread;
|
||||
int refcount;
|
||||
|
||||
Eina_Bool exists : 1;
|
||||
};
|
||||
|
||||
static const char _ethumb_dbus_bus_name[] = "org.enlightenment.Ethumb";
|
||||
static const char _ethumb_dbus_interface[] = "org.enlightenment.Ethumb";
|
||||
static const char _ethumb_dbus_objects_interface[] = "org.enlightenment.Ethumb.objects";
|
||||
|
@ -463,6 +483,54 @@ error:
|
|||
_ethumb_client_report_connect(client, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
_ethumb_client_exists_heavy(void *data, Ecore_Thread *thread)
|
||||
{
|
||||
Ethumb_Async_Exists *async = data;
|
||||
|
||||
async->exists = ethumb_exists(async->dup);
|
||||
}
|
||||
|
||||
static void
|
||||
_ethumb_client_exists_end(void *data, Ecore_Thread *thread)
|
||||
{
|
||||
Ethumb_Async_Exists *async = data;
|
||||
Ethumb *tmp = async->source->ethumb;
|
||||
|
||||
async->source->ethumb = async->dup;
|
||||
async->source->ethumb_dirty = ethumb_cmp(tmp, async->dup);
|
||||
async->exists_cb(async->source, (Ethumb_Exists*) async, async->exists, (void*) async->data);
|
||||
async->source->ethumb = tmp;
|
||||
|
||||
ethumb_free(async->dup);
|
||||
async->source->refcount--;
|
||||
|
||||
if (async->source->delete_me == EINA_TRUE)
|
||||
ethumb_client_disconnect(async->source);
|
||||
|
||||
free(async);
|
||||
}
|
||||
|
||||
static void
|
||||
_ethumb_client_exists_cancel(void *data, Ecore_Thread *thread)
|
||||
{
|
||||
Ethumb_Async_Exists *async = data;
|
||||
Ethumb *tmp = async->source->ethumb;
|
||||
|
||||
async->source->ethumb = async->dup;
|
||||
async->source->ethumb_dirty = ethumb_cmp(tmp, async->dup);
|
||||
async->exists_cb(async->source, (Ethumb_Exists*) async, EINA_FALSE, (void*) async->data);
|
||||
async->source->ethumb = tmp;
|
||||
|
||||
ethumb_free(async->dup);
|
||||
async->source->refcount--;
|
||||
|
||||
if (async->source->delete_me == EINA_TRUE)
|
||||
ethumb_client_disconnect(async->source);
|
||||
|
||||
free(async);
|
||||
}
|
||||
|
||||
/**
|
||||
* @endcond
|
||||
*/
|
||||
|
@ -652,6 +720,10 @@ ethumb_client_disconnect(Ethumb_Client *client)
|
|||
|
||||
EINA_SAFETY_ON_NULL_RETURN(client);
|
||||
|
||||
client->delete_me = EINA_TRUE;
|
||||
if (client->refcount > 0)
|
||||
return ;
|
||||
|
||||
if (!client->connected)
|
||||
goto end_connection;
|
||||
|
||||
|
@ -1218,22 +1290,22 @@ ethumb_client_generate_cancel(Ethumb_Client *client, int id, Ethumb_Client_Gener
|
|||
l = client->pending_add;
|
||||
while (l)
|
||||
{
|
||||
struct _ethumb_pending_add *pending = l->data;
|
||||
if (pending->id != id32)
|
||||
struct _ethumb_pending_add *pending_add = l->data;
|
||||
if (pending_add->id != id32)
|
||||
{
|
||||
l = l->next;
|
||||
continue;
|
||||
}
|
||||
client->pending_add = eina_list_remove_list(client->pending_add, l);
|
||||
eina_stringshare_del(pending->file);
|
||||
eina_stringshare_del(pending->key);
|
||||
eina_stringshare_del(pending->thumb);
|
||||
eina_stringshare_del(pending->thumb_key);
|
||||
dbus_pending_call_cancel(pending->pending_call);
|
||||
dbus_pending_call_unref(pending->pending_call);
|
||||
if (pending->free_data)
|
||||
pending->free_data(pending->data);
|
||||
free(pending);
|
||||
eina_stringshare_del(pending_add->file);
|
||||
eina_stringshare_del(pending_add->key);
|
||||
eina_stringshare_del(pending_add->thumb);
|
||||
eina_stringshare_del(pending_add->thumb_key);
|
||||
dbus_pending_call_cancel(pending_add->pending_call);
|
||||
dbus_pending_call_unref(pending_add->pending_call);
|
||||
if (pending_add->free_data)
|
||||
pending_add->free_data(pending_add->data);
|
||||
free(pending_add);
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
|
@ -1244,20 +1316,20 @@ ethumb_client_generate_cancel(Ethumb_Client *client, int id, Ethumb_Client_Gener
|
|||
l = client->pending_gen;
|
||||
while (l)
|
||||
{
|
||||
struct _ethumb_pending_gen *pending = l->data;
|
||||
if (pending->id != id32)
|
||||
struct _ethumb_pending_gen *pending_gen = l->data;
|
||||
if (pending_gen->id != id32)
|
||||
{
|
||||
l = l->next;
|
||||
continue;
|
||||
}
|
||||
client->pending_gen = eina_list_remove_list(client->pending_gen, l);
|
||||
eina_stringshare_del(pending->file);
|
||||
eina_stringshare_del(pending->key);
|
||||
eina_stringshare_del(pending->thumb);
|
||||
eina_stringshare_del(pending->thumb_key);
|
||||
if (pending->free_data)
|
||||
pending->free_data(pending->data);
|
||||
free(pending);
|
||||
eina_stringshare_del(pending_gen->file);
|
||||
eina_stringshare_del(pending_gen->key);
|
||||
eina_stringshare_del(pending_gen->thumb);
|
||||
eina_stringshare_del(pending_gen->thumb_key);
|
||||
if (pending_gen->free_data)
|
||||
pending_gen->free_data(pending_gen->data);
|
||||
free(pending_gen);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1781,15 +1853,15 @@ ethumb_client_category_get(const Ethumb_Client *client)
|
|||
* @param client the client instance to use. Must @b not be @c
|
||||
* NULL. May be pending connected (can be called before @c
|
||||
* connected_cb)
|
||||
* @param time duration (in seconds). Defaults to 3 seconds.
|
||||
* @param t duration (in seconds). Defaults to 3 seconds.
|
||||
*/
|
||||
EAPI void
|
||||
ethumb_client_video_time_set(Ethumb_Client *client, float time)
|
||||
ethumb_client_video_time_set(Ethumb_Client *client, float t)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN(client);
|
||||
|
||||
client->ethumb_dirty = 1;
|
||||
ethumb_video_time_set(client->ethumb, time);
|
||||
ethumb_video_time_set(client->ethumb, t);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2047,12 +2119,67 @@ ethumb_client_thumb_path_get(Ethumb_Client *client, const char **path, const cha
|
|||
*
|
||||
* @return @c EINA_TRUE if it exists, @c EINA_FALSE otherwise.
|
||||
*/
|
||||
EAPI Eina_Bool
|
||||
ethumb_client_thumb_exists(Ethumb_Client *client)
|
||||
EAPI Ethumb_Exists *
|
||||
ethumb_client_thumb_exists(Ethumb_Client *client, Ethumb_Client_Thumb_Exists_Cb exists_cb, const void *data)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(client, 0);
|
||||
Ethumb_Async_Exists *async;
|
||||
|
||||
return ethumb_exists(client->ethumb);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(client, NULL);
|
||||
|
||||
async = malloc(sizeof (Ethumb_Async_Exists));
|
||||
if (!async)
|
||||
{
|
||||
exists_cb(client, NULL, EINA_FALSE, (void*) data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
async->dup = ethumb_dup(client->ethumb);
|
||||
async->source = client;
|
||||
async->source->refcount++;
|
||||
async->exists_cb = exists_cb;
|
||||
async->data = data;
|
||||
async->exists = EINA_FALSE;
|
||||
|
||||
async->refcount = 1;
|
||||
async->thread = ecore_thread_run(_ethumb_client_exists_heavy,
|
||||
_ethumb_client_exists_end,
|
||||
_ethumb_client_exists_cancel,
|
||||
async);
|
||||
|
||||
return (Ethumb_Exists*) async;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel an ongoing exists request.
|
||||
*
|
||||
* @param exists the request to cancel.
|
||||
*/
|
||||
EAPI void
|
||||
ethumb_client_thumb_exists_cancel(Ethumb_Exists *exists)
|
||||
{
|
||||
Ethumb_Async_Exists *async = (Ethumb_Async_Exists*) exists;
|
||||
|
||||
async->refcount--;
|
||||
|
||||
if (async->refcount > 0) return ;
|
||||
|
||||
ecore_thread_cancel(async->thread);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an exists request was cancelled.
|
||||
*
|
||||
* @param exists the request to check.
|
||||
* @result return EINA_TRUE if the request was cancelled.
|
||||
*/
|
||||
EAPI Eina_Bool
|
||||
ethumb_client_thumb_exists_check(Ethumb_Exists *exists)
|
||||
{
|
||||
Ethumb_Async_Exists *async = (Ethumb_Async_Exists*) exists;
|
||||
|
||||
if (!async) return EINA_TRUE;
|
||||
|
||||
return ecore_thread_check(async->thread);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef __ETHUMB_CLIENT_H__
|
||||
#define __ETHUMB_CLIENT_H__ 1
|
||||
|
||||
#include <Ecore.h>
|
||||
#include <Ethumb.h>
|
||||
|
||||
#ifdef EAPI
|
||||
|
@ -63,6 +64,15 @@ extern "C" {
|
|||
*/
|
||||
typedef struct _Ethumb_Client Ethumb_Client;
|
||||
|
||||
/**
|
||||
* @brief client exists request handle.
|
||||
*
|
||||
* The exists request handle is created by ethumb_client_thumb_exists(),
|
||||
* automatically destroyed when it end and cancelled when requested by
|
||||
* ethumb_client_thumb_exists_cancel().
|
||||
*/
|
||||
typedef struct _Ethumb_Exists Ethumb_Exists;
|
||||
|
||||
/**
|
||||
* @brief reports results of ethumb_client_connect()
|
||||
*
|
||||
|
@ -100,6 +110,19 @@ typedef void (*Ethumb_Client_Die_Cb)(void *data, Ethumb_Client *client);
|
|||
*/
|
||||
typedef void (*Ethumb_Client_Generate_Cb)(void *data, Ethumb_Client *client, int id, const char *file, const char *key, const char *thumb_path, const char *thumb_key, Eina_Bool success);
|
||||
|
||||
/**
|
||||
* @brief report results of ethumb_client_thumb_exists().
|
||||
*
|
||||
* @param client handle of the current connection to server.
|
||||
* @param exists EINA_TRUE if the thumbnail exists.
|
||||
* @param data extra context given to ethumb_client_thumb_exists().
|
||||
*
|
||||
* During the execution of the callback the state of the @p client is
|
||||
* temporarily realy restored to what it was when the call to
|
||||
* ethumb_client_thumb_exists() was done.
|
||||
*/
|
||||
typedef void (*Ethumb_Client_Thumb_Exists_Cb)(Ethumb_Client *client, Ethumb_Exists *thread, Eina_Bool exists, void *data);
|
||||
|
||||
/**
|
||||
* @brief reports results of ethumb_client_generate_cancel()
|
||||
*
|
||||
|
@ -171,7 +194,9 @@ EAPI Eina_Bool ethumb_client_file_set(Ethumb_Client *client, const char *path, c
|
|||
EAPI void ethumb_client_file_get(Ethumb_Client *client, const char **path, const char **key);
|
||||
EAPI void ethumb_client_file_free(Ethumb_Client *client);
|
||||
|
||||
EAPI Eina_Bool ethumb_client_thumb_exists(Ethumb_Client *client);
|
||||
EAPI Ethumb_Exists *ethumb_client_thumb_exists(Ethumb_Client *client, Ethumb_Client_Thumb_Exists_Cb exists_cb, const void *data);
|
||||
EAPI void ethumb_client_thumb_exists_cancel(Ethumb_Exists *exists);
|
||||
EAPI Eina_Bool ethumb_client_thumb_exists_check(Ethumb_Exists *exists);
|
||||
EAPI int ethumb_client_generate(Ethumb_Client *client, Ethumb_Client_Generate_Cb generated_cb, const void *data, Eina_Free_Cb free_data);
|
||||
EAPI void ethumb_client_generate_cancel(Ethumb_Client *client, int id, Ethumb_Client_Generate_Cancel_Cb cancel_cb, const void *data, Eina_Free_Cb free_data);
|
||||
EAPI void ethumb_client_generate_cancel_all(Ethumb_Client *client);
|
||||
|
|
Loading…
Reference in New Issue