Add an new executable to help on recordings maintenance
An issue that currently happens in Exactness is that we don't have any way to debug the recordings. Only debug information can help us to figure out what data is stored inside the rec files. Three commands are available: - Clean: remove bad timestamp events and duplicate events - Add a delay: because of the first event is directly treated if no first timestamp is present, we need a way to fix recordings by adding them a delay before the first event. - List information: display the list of events, as vieet doesn't work at all. Really helpful to figure out bugs.
This commit is contained in:
parent
4effc37ab0
commit
a21c2f39cc
|
@ -1 +1,2 @@
|
|||
/exactness
|
||||
/exactness_helper
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
bin_PROGRAMS = exactness
|
||||
bin_PROGRAMS = exactness exactness_helper
|
||||
|
||||
exactness_SOURCES = \
|
||||
exactness.c \
|
||||
|
@ -9,11 +9,18 @@ exactness_SOURCES = \
|
|||
scheduler.c \
|
||||
run_test.c
|
||||
|
||||
exactness_helper_SOURCES = exactness_helper.c
|
||||
|
||||
exactness_LDADD = \
|
||||
@EFL_LIBS@
|
||||
|
||||
exactness_helper_LDADD = \
|
||||
@EFL_LIBS@ ../lib/libexactness.la
|
||||
|
||||
exactness_CFLAGS = \
|
||||
@EFL_CFLAGS@ \
|
||||
-I$(top_srcdir)/src/lib \
|
||||
-DPACKAGE_LIBDIR=\"$(libdir)\" \
|
||||
-DPACKAGE_DATADIR=\"$(datadir)\"
|
||||
|
||||
exactness_helper_CFLAGS = @EFL_CFLAGS@ -I$(top_srcdir)/src/lib
|
||||
|
|
|
@ -0,0 +1,246 @@
|
|||
#include <Ecore.h>
|
||||
#include <Ecore_Getopt.h>
|
||||
|
||||
#include "tsuite_file_data.h"
|
||||
|
||||
static const char *
|
||||
_event_name_get(const Variant_st *v)
|
||||
{
|
||||
switch(tsuite_event_mapping_type_get(v->t.type))
|
||||
{
|
||||
case TSUITE_EVENT_MOUSE_IN: return "Mouse In";
|
||||
case TSUITE_EVENT_MOUSE_OUT: return "Mouse Out";
|
||||
case TSUITE_EVENT_MOUSE_DOWN: return "Mouse Down";
|
||||
case TSUITE_EVENT_MOUSE_UP: return "Mouse Up";
|
||||
case TSUITE_EVENT_MOUSE_MOVE: return "Mouse Move";
|
||||
case TSUITE_EVENT_MOUSE_WHEEL: return "Mouse Wheel";
|
||||
case TSUITE_EVENT_MULTI_DOWN: return "Multi Down";
|
||||
case TSUITE_EVENT_MULTI_UP: return "Multi Up";
|
||||
case TSUITE_EVENT_MULTI_MOVE: return "Multi Move";
|
||||
case TSUITE_EVENT_KEY_DOWN: return "Key Down";
|
||||
case TSUITE_EVENT_KEY_UP: return "Key Up";
|
||||
case TSUITE_EVENT_KEY_DOWN_WITH_KEYCODE: return "Key Down with Keycode";
|
||||
case TSUITE_EVENT_KEY_UP_WITH_KEYCODE: return "Key Up with Keycode";
|
||||
case TSUITE_EVENT_TAKE_SHOT: return "Take shot";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
_event_struct_len_get(Tsuite_Event_Type type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case TSUITE_EVENT_MOUSE_IN: case TSUITE_EVENT_MOUSE_OUT: return sizeof(mouse_in_mouse_out);
|
||||
case TSUITE_EVENT_MOUSE_DOWN: case TSUITE_EVENT_MOUSE_UP: return sizeof(mouse_down_mouse_up);
|
||||
case TSUITE_EVENT_MOUSE_MOVE: return sizeof(mouse_move);
|
||||
case TSUITE_EVENT_MOUSE_WHEEL: return sizeof(mouse_wheel);
|
||||
case TSUITE_EVENT_MULTI_DOWN: case TSUITE_EVENT_MULTI_UP: return sizeof(multi_move);
|
||||
case TSUITE_EVENT_MULTI_MOVE: return sizeof(multi_event);
|
||||
case TSUITE_EVENT_KEY_DOWN: case TSUITE_EVENT_KEY_UP: return sizeof(key_down_key_up);
|
||||
case TSUITE_EVENT_KEY_DOWN_WITH_KEYCODE: case TSUITE_EVENT_KEY_UP_WITH_KEYCODE: return sizeof(key_down_key_up_with_keycode);
|
||||
case TSUITE_EVENT_TAKE_SHOT: return sizeof(take_screenshot);
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_event_specific_info_get(const Variant_st *v, char output[1024])
|
||||
{
|
||||
switch(tsuite_event_mapping_type_get(v->t.type))
|
||||
{
|
||||
case TSUITE_EVENT_MOUSE_DOWN:
|
||||
{
|
||||
mouse_down_mouse_up *t = v->data;
|
||||
sprintf(output, "Button %d Flags %d", t->b, t->flags);
|
||||
break;
|
||||
}
|
||||
case TSUITE_EVENT_MOUSE_UP:
|
||||
{
|
||||
mouse_down_mouse_up *t = v->data;
|
||||
sprintf(output, "Button %d Flags %d", t->b, t->flags);
|
||||
break;
|
||||
}
|
||||
case TSUITE_EVENT_MOUSE_MOVE:
|
||||
{
|
||||
mouse_move *t = v->data;
|
||||
sprintf(output, "X %d Y %d", t->x, t->y);
|
||||
break;
|
||||
}
|
||||
case TSUITE_EVENT_MOUSE_WHEEL:
|
||||
{
|
||||
mouse_wheel *t = v->data;
|
||||
sprintf(output, "Direction %d Z %d", t->direction, t->z);
|
||||
break;
|
||||
}
|
||||
case TSUITE_EVENT_MULTI_DOWN: case TSUITE_EVENT_MULTI_UP:
|
||||
{
|
||||
multi_event *t = v->data;
|
||||
sprintf(output, "D %d X %d Y %d Rad %f RadX %f RadY %f Pres %f Ang %f FX %f FY %f Flags %d",
|
||||
t->d, t->x, t->y, t->rad, t->radx, t->rady, t->pres, t->ang, t->fx, t->fy, t->flags);
|
||||
break;
|
||||
}
|
||||
case TSUITE_EVENT_MULTI_MOVE:
|
||||
{
|
||||
multi_move *t = v->data;
|
||||
sprintf(output, "D %d X %d Y %d Rad %f RadX %f RadY %f Pres %f Ang %f FX %f FY %f",
|
||||
t->d, t->x, t->y, t->rad, t->radx, t->rady, t->pres, t->ang, t->fx, t->fy);
|
||||
break;
|
||||
}
|
||||
case TSUITE_EVENT_KEY_UP: case TSUITE_EVENT_KEY_DOWN:
|
||||
{
|
||||
key_down_key_up *t = v->data;
|
||||
sprintf(output, "Keyname %s Key %s String %s Compose %s",
|
||||
t->keyname, t->key, t->string, t->compose);
|
||||
break;
|
||||
}
|
||||
case TSUITE_EVENT_KEY_DOWN_WITH_KEYCODE: case TSUITE_EVENT_KEY_UP_WITH_KEYCODE:
|
||||
{
|
||||
key_down_key_up_with_keycode *t = v->data;
|
||||
sprintf(output, "Keyname %s Key %s String %s Compose %s Keycode %d",
|
||||
t->keyname, t->key, t->string, t->compose, t->keycode);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
output[0] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
static const Ecore_Getopt optdesc = {
|
||||
"exactness_helper",
|
||||
"%prog [options] <rec file>",
|
||||
NULL,
|
||||
"(C) 2016 Enlightenment",
|
||||
"BSD",
|
||||
"Helper for Exactness",
|
||||
0,
|
||||
{
|
||||
ECORE_GETOPT_STORE_USHORT('d', "delay", "Delay the given recording by a given time (in seconds)."),
|
||||
ECORE_GETOPT_STORE_TRUE('c', "clean", "Clean the given recording from wrong events."),
|
||||
ECORE_GETOPT_STORE_TRUE('l', "list", "List the events of the given recording"),
|
||||
|
||||
ECORE_GETOPT_LICENSE('L', "license"),
|
||||
ECORE_GETOPT_COPYRIGHT('C', "copyright"),
|
||||
ECORE_GETOPT_VERSION('V', "version"),
|
||||
ECORE_GETOPT_HELP('h', "help"),
|
||||
ECORE_GETOPT_SENTINEL
|
||||
}
|
||||
};
|
||||
|
||||
static Eina_Bool
|
||||
_is_hook_duplicate(const Variant_st *cur_v, const Variant_st *prev_v)
|
||||
{
|
||||
if (!prev_v) return EINA_FALSE;
|
||||
Tsuite_Event_Type cur_type = tsuite_event_mapping_type_get(cur_v->t.type);
|
||||
Tsuite_Event_Type prev_type = tsuite_event_mapping_type_get(prev_v->t.type);
|
||||
if (cur_type == prev_type &&
|
||||
!memcmp(cur_v->data, prev_v->data, _event_struct_len_get(cur_type))) return EINA_TRUE;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
const char *rec_file = NULL;
|
||||
int ret = 0, args = 0;
|
||||
unsigned short delay = 0;
|
||||
Eina_Bool want_quit, clean = EINA_FALSE, list_get = EINA_FALSE;
|
||||
Ecore_Getopt_Value values[] = {
|
||||
ECORE_GETOPT_VALUE_USHORT(delay),
|
||||
ECORE_GETOPT_VALUE_BOOL(clean),
|
||||
ECORE_GETOPT_VALUE_BOOL(list_get),
|
||||
|
||||
ECORE_GETOPT_VALUE_BOOL(want_quit),
|
||||
ECORE_GETOPT_VALUE_BOOL(want_quit),
|
||||
ECORE_GETOPT_VALUE_BOOL(want_quit),
|
||||
ECORE_GETOPT_VALUE_BOOL(want_quit),
|
||||
ECORE_GETOPT_VALUE_NONE
|
||||
};
|
||||
|
||||
ecore_init();
|
||||
want_quit = EINA_FALSE;
|
||||
|
||||
args = ecore_getopt_parse(&optdesc, values, argc, argv);
|
||||
if (args < 0)
|
||||
{
|
||||
fprintf(stderr, "Failed parsing arguments.\n");
|
||||
ret = 1;
|
||||
goto end;
|
||||
}
|
||||
else if (want_quit)
|
||||
{
|
||||
ret = 1;
|
||||
goto end;
|
||||
}
|
||||
else if (args == argc)
|
||||
{
|
||||
fprintf(stderr, "Expected rec file as the last argument..\n");
|
||||
ecore_getopt_help(stderr, &optdesc);
|
||||
ret = 1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
rec_file = argv[args];
|
||||
Timer_Data td;
|
||||
Lists_st *list = read_events(rec_file, &td);
|
||||
|
||||
if (clean)
|
||||
{
|
||||
Variant_st *v;
|
||||
Eina_List *itr, *itr2;
|
||||
EINA_LIST_FOREACH_SAFE(list->variant_list, itr, itr2, v)
|
||||
{
|
||||
if (!evt_time_get(0, v))
|
||||
list->variant_list = eina_list_remove_list(list->variant_list, itr);
|
||||
else
|
||||
{
|
||||
if (_is_hook_duplicate(v, eina_list_data_get(eina_list_prev(itr))))
|
||||
list->variant_list = eina_list_remove_list(list->variant_list, itr);
|
||||
}
|
||||
}
|
||||
if (!list->first_timestamp)
|
||||
{
|
||||
list->first_timestamp = evt_time_get(0, eina_list_data_get(list->variant_list));
|
||||
}
|
||||
}
|
||||
|
||||
if (delay)
|
||||
{
|
||||
delay *= 1000;
|
||||
|
||||
if (!list->first_timestamp)
|
||||
{
|
||||
list->first_timestamp = evt_time_get(0, eina_list_data_get(list->variant_list));
|
||||
}
|
||||
list->first_timestamp -= delay;
|
||||
}
|
||||
|
||||
if (list_get)
|
||||
{
|
||||
Variant_st *v;
|
||||
Eina_List *itr;
|
||||
printf("First timestamp: ");
|
||||
if (list->first_timestamp) printf("%u\n", list->first_timestamp);
|
||||
else printf("undefined\n");
|
||||
EINA_LIST_FOREACH(list->variant_list, itr, v)
|
||||
{
|
||||
char specific_output[1024];
|
||||
unsigned int timestamp = evt_time_get(0, v);
|
||||
if (!timestamp) printf("BAD_TIME: ");
|
||||
else printf("%.3f: ", (list->first_timestamp ? timestamp - list->first_timestamp : timestamp) / 1000.0);
|
||||
printf("%s", _event_name_get(v));
|
||||
_event_specific_info_get(v, specific_output);
|
||||
if (*specific_output) printf(" - %s", specific_output);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
write_events(rec_file, list);
|
||||
|
||||
end:
|
||||
ecore_shutdown();
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -18,7 +18,7 @@ libexactness_la_SOURCES = \
|
|||
tsuite_evas_hook.c \
|
||||
tsuite_file_data.c
|
||||
|
||||
libexactness_la_LDFLAGS = -module -avoid-version -rdynamic
|
||||
libexactness_la_LDFLAGS = -avoid-version -rdynamic
|
||||
libexactness_la_DEPENDENCIES = $(top_builddir)/config.h
|
||||
libexactness_la_LIBADD = @EFL_LIBS@
|
||||
libexactness_la_CFLAGS = @EFL_CFLAGS@
|
||||
|
|
|
@ -65,7 +65,7 @@ _tsuite_verbosef(const char *fmt, ...)
|
|||
* @ingroup Tsuite
|
||||
*/
|
||||
|
||||
static unsigned int
|
||||
unsigned int
|
||||
evt_time_get(unsigned int tm, Variant_st *v)
|
||||
{
|
||||
switch(tsuite_event_mapping_type_get(v->t.type))
|
||||
|
|
|
@ -211,7 +211,7 @@ write_events(const char *filename, Lists_st *vr_list)
|
|||
}
|
||||
|
||||
Lists_st *
|
||||
read_events(char *filename, Timer_Data *td)
|
||||
read_events(const char *filename, Timer_Data *td)
|
||||
{
|
||||
Lists_st *vr_list;
|
||||
Eet_File *fp = eet_open(filename, EET_FILE_MODE_READ);
|
||||
|
|
|
@ -1,11 +1,40 @@
|
|||
#ifndef _TSUITE_EVAS_HOOK_H
|
||||
#define _TSUITE_EVAS_HOOK_H
|
||||
|
||||
#include <Evas.h>
|
||||
#include <Eet.h>
|
||||
|
||||
#define CACHE_FILE_ENTRY "cache"
|
||||
|
||||
/* Macro declaring a function argument to be unused */
|
||||
#define __UNUSED__ __attribute__((unused))
|
||||
|
||||
#ifdef EAPI
|
||||
# undef EAPI
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifdef EXACTNESS_BUILD
|
||||
# ifdef DLL_EXPORT
|
||||
# define EAPI __declspec(dllexport)
|
||||
# else
|
||||
# define EAPI
|
||||
# endif /* ! DLL_EXPORT */
|
||||
# else
|
||||
# define EAPI __declspec(dllimport)
|
||||
# endif /* ! EXACTNESS_BUILD */
|
||||
#else
|
||||
# ifdef __GNUC__
|
||||
# if __GNUC__ >= 4
|
||||
# define EAPI __attribute__ ((visibility("default")))
|
||||
# else
|
||||
# define EAPI
|
||||
# endif
|
||||
# else
|
||||
# define EAPI
|
||||
# endif
|
||||
#endif /* ! _WIN32 */
|
||||
|
||||
enum _Tsuite_Event_Type
|
||||
{ /* Add any supported events here */
|
||||
TSUITE_EVENT_NOT_SUPPORTED = 0,
|
||||
|
@ -220,7 +249,9 @@ const char * tsuite_event_mapping_type_str_get(Tsuite_Event_Type t);
|
|||
const char * _variant_type_get(const void *data, Eina_Bool *unknow);
|
||||
Eina_Bool _variant_type_set(const char *type, void *data, Eina_Bool unknow);
|
||||
|
||||
Lists_st * free_events(Lists_st *st, char *recording);
|
||||
void write_events(const char *filename, Lists_st *vr_list);
|
||||
Lists_st *read_events(char *filename, Timer_Data *td);
|
||||
EAPI Tsuite_Event_Type tsuite_event_mapping_type_get(const char *name);
|
||||
EAPI Lists_st * free_events(Lists_st *st, char *recording);
|
||||
EAPI void write_events(const char *filename, Lists_st *vr_list);
|
||||
EAPI Lists_st *read_events(const char *filename, Timer_Data *td);
|
||||
EAPI unsigned int evt_time_get(unsigned int tm, Variant_st *v);
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue