XMMS2

src/include/xmms/xmms_object.h

Go to the documentation of this file.
00001 /*  XMMS2 - X Music Multiplexer System
00002  *  Copyright (C) 2003-2009 XMMS2 Team
00003  *
00004  *  PLUGINS ARE NOT CONSIDERED TO BE DERIVED WORK !!!
00005  *
00006  *  This library is free software; you can redistribute it and/or
00007  *  modify it under the terms of the GNU Lesser General Public
00008  *  License as published by the Free Software Foundation; either
00009  *  version 2.1 of the License, or (at your option) any later version.
00010  *
00011  *  This library is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  *  Lesser General Public License for more details.
00015  */
00016 
00017 
00018 
00019 
00020 #ifndef __XMMS_OBJECT_H__
00021 #define __XMMS_OBJECT_H__
00022 
00023 #include <glib.h>
00024 #include "xmms/xmms_error.h"
00025 #include "xmmsc/xmmsc_idnumbers.h"
00026 #include "xmmsc/xmmsv.h"
00027 #include "xmmsc/xmmsv_coll.h"
00028 
00029 #define XMMS_OBJECT_MID 0x00455574
00030 
00031 G_BEGIN_DECLS
00032 
00033 struct xmms_object_St;
00034 typedef struct xmms_object_St xmms_object_t;
00035 typedef struct xmms_object_cmd_desc_St xmms_object_cmd_desc_t;
00036 
00037 typedef void (*xmms_object_destroy_func_t) (xmms_object_t *object);
00038 
00039 /** @addtogroup Object
00040   * @{
00041   */
00042 struct xmms_object_St {
00043     guint32 id;
00044     GMutex *mutex;
00045 
00046     GTree *signals;
00047     GTree *cmds;
00048 
00049     gint ref;
00050     xmms_object_destroy_func_t destroy_func;
00051 };
00052 
00053 
00054 /* Convenience wrapper to create #xmmsv_t from GLib types. */
00055 xmmsv_t *xmms_convert_and_kill_list (GList *list);
00056 xmmsv_t *xmms_convert_and_kill_dict (GTree *dict);
00057 xmmsv_t *xmms_convert_and_kill_string (gchar *str);
00058 xmmsv_t *xmms_convert_and_kill_bin (GString *gs);
00059 
00060 int xmms_bin_to_gstring (xmmsv_t *value, GString **gs);
00061 int dummy_identity (xmmsv_t *value, xmmsv_t **arg);
00062 gboolean check_string_list (xmmsv_t *list);
00063 
00064 
00065 /** @} */
00066 
00067 typedef void (*xmms_object_handler_t) (xmms_object_t *object, xmmsv_t *data, gpointer userdata);
00068 
00069 #define XMMS_OBJECT_CMD_MAX_ARGS 6
00070 typedef struct {
00071     xmmsv_t *values[XMMS_OBJECT_CMD_MAX_ARGS];
00072     xmmsv_t *retval;
00073     xmms_error_t error;
00074 } xmms_object_cmd_arg_t;
00075 
00076 typedef void (*xmms_object_cmd_func_t) (xmms_object_t *object, xmms_object_cmd_arg_t *arg);
00077 
00078 struct xmms_object_cmd_desc_St {
00079     xmms_object_cmd_func_t func;
00080     xmmsv_type_t retval;
00081     xmmsv_type_t args[XMMS_OBJECT_CMD_MAX_ARGS];
00082 };
00083 
00084 #define XMMS_OBJECT(p) ((xmms_object_t *)p)
00085 #define XMMS_IS_OBJECT(p) (XMMS_OBJECT (p)->id == XMMS_OBJECT_MID)
00086 
00087 void xmms_object_cleanup (xmms_object_t *object);
00088 
00089 void xmms_object_connect (xmms_object_t *object, guint32 signalid,
00090               xmms_object_handler_t handler, gpointer userdata);
00091 
00092 void xmms_object_disconnect (xmms_object_t *object, guint32 signalid,
00093                  xmms_object_handler_t handler, gpointer userdata);
00094 
00095 void xmms_object_emit (xmms_object_t *object, guint32 signalid, xmmsv_t *data);
00096 
00097 void xmms_object_emit_f (xmms_object_t *object, guint32 signalid,
00098              xmmsv_type_t type, ...);
00099 
00100 void xmms_object_cmd_arg_init (xmms_object_cmd_arg_t *arg);
00101 
00102 void xmms_object_cmd_add (xmms_object_t *object, guint cmdid, const xmms_object_cmd_desc_t *desc);
00103 
00104 void xmms_object_cmd_call (xmms_object_t *object, guint cmdid, xmms_object_cmd_arg_t *arg);
00105 
00106 /* Some minor macro-magic. XMMS_CMD_DEFINE and XMMS_CMD_FUNC
00107  * are the only ones to be used directly */
00108 
00109 #define __XMMS_CMD_INIT_ARG_FULL(argn, argtypecode, extract_func) \
00110     argtypecode argval##argn; \
00111     g_return_if_fail (extract_func (arg->values[argn], &argval##argn));
00112 
00113 #define __XMMS_CMD_INIT_ARG(argn, argtype, argtypecode) \
00114     __XMMS_CMD_INIT_ARG_FULL(argn, argtypecode, xmmsv_get_##argtype)
00115 
00116 #define __XMMS_CMD_INIT_ARG_NONE(a)
00117 #define __XMMS_CMD_INIT_ARG_STRING(a) __XMMS_CMD_INIT_ARG(a, string, const gchar *)
00118 #define __XMMS_CMD_INIT_ARG_INT32(a)  __XMMS_CMD_INIT_ARG(a, int,  gint)
00119 #define __XMMS_CMD_INIT_ARG_COLL(a)   __XMMS_CMD_INIT_ARG(a, coll, xmmsv_coll_t *)
00120 #define __XMMS_CMD_INIT_ARG_BIN(a)    __XMMS_CMD_INIT_ARG_FULL(a, GString *, xmms_bin_to_gstring)
00121 #define __XMMS_CMD_INIT_ARG_LIST(a)   __XMMS_CMD_INIT_ARG_FULL(a, xmmsv_t *, dummy_identity)
00122 #define __XMMS_CMD_INIT_ARG_DICT(a)   __XMMS_CMD_INIT_ARG_FULL(a, xmmsv_t *, dummy_identity)
00123 
00124 #define __XMMS_CMD_PRINT_ARG_NONE(a)
00125 #define __XMMS_CMD_PRINT_ARG_STRING(a) , argval##a
00126 #define __XMMS_CMD_PRINT_ARG_INT32(a)  , argval##a
00127 #define __XMMS_CMD_PRINT_ARG_COLL(a)   , argval##a
00128 #define __XMMS_CMD_PRINT_ARG_BIN(a)    , argval##a
00129 #define __XMMS_CMD_PRINT_ARG_LIST(a)   , argval##a
00130 #define __XMMS_CMD_PRINT_ARG_DICT(a)   , argval##a
00131 
00132 #define __XMMS_CMD_DO_RETVAL_NONE() arg->retval = xmmsv_new_none();
00133 #define __XMMS_CMD_DO_RETVAL_DICT() arg->retval = xmms_convert_and_kill_dict
00134 #define __XMMS_CMD_DO_RETVAL_INT32() arg->retval = xmmsv_new_int
00135 #define __XMMS_CMD_DO_RETVAL_LIST() arg->retval = xmms_convert_and_kill_list
00136 #define __XMMS_CMD_DO_RETVAL_STRING() arg->retval = xmms_convert_and_kill_string
00137 #define __XMMS_CMD_DO_RETVAL_COLL() arg->retval = xmmsv_new_coll
00138 #define __XMMS_CMD_DO_RETVAL_BIN() arg->retval =
00139 
00140 #define __XMMS_CMD_DO_RETTYPE_NONE() void
00141 #define __XMMS_CMD_DO_RETTYPE_STRING() char *
00142 #define __XMMS_CMD_DO_RETTYPE_INT32()  gint32
00143 #define __XMMS_CMD_DO_RETTYPE_COLL(a)  xmmsv_coll_t *
00144 #define __XMMS_CMD_DO_RETTYPE_BIN(a)   xmmsv_t *
00145 #define __XMMS_CMD_DO_RETTYPE_LIST(a)  GList *
00146 #define __XMMS_CMD_DO_RETTYPE_DICT(a)  GTree *
00147 
00148 #define __XMMS_CMD_DO_ARGTYPE_NONE 
00149 #define __XMMS_CMD_DO_ARGTYPE_STRING , const char *
00150 #define __XMMS_CMD_DO_ARGTYPE_INT32  , gint32
00151 #define __XMMS_CMD_DO_ARGTYPE_COLL  , xmmsv_coll_t *
00152 #define __XMMS_CMD_DO_ARGTYPE_BIN   , GString *
00153 #define __XMMS_CMD_DO_ARGTYPE_LIST  , xmmsv_t *
00154 #define __XMMS_CMD_DO_ARGTYPE_DICT  , xmmsv_t *
00155 
00156 
00157 #define XMMS_CMD_DEFINE6(cmdid, realfunc, argtype0, _rettype, argtype1, argtype2, argtype3, argtype4, argtype5, argtype6) \
00158 \
00159     static __XMMS_CMD_DO_RETTYPE_##_rettype() realfunc (argtype0 __XMMS_CMD_DO_ARGTYPE_##argtype1 __XMMS_CMD_DO_ARGTYPE_##argtype2 __XMMS_CMD_DO_ARGTYPE_##argtype3 __XMMS_CMD_DO_ARGTYPE_##argtype4 __XMMS_CMD_DO_ARGTYPE_##argtype5 __XMMS_CMD_DO_ARGTYPE_##argtype6, xmms_error_t *); \
00160 \
00161 static void \
00162 __int_xmms_cmd_##cmdid (xmms_object_t *object, xmms_object_cmd_arg_t *arg) \
00163 { \
00164 g_return_if_fail (XMMS_IS_OBJECT (object)); \
00165 __XMMS_CMD_INIT_ARG_##argtype1 (0) \
00166 __XMMS_CMD_INIT_ARG_##argtype2 (1) \
00167 __XMMS_CMD_INIT_ARG_##argtype3 (2) \
00168 __XMMS_CMD_INIT_ARG_##argtype4 (3) \
00169 __XMMS_CMD_INIT_ARG_##argtype5 (4) \
00170 __XMMS_CMD_INIT_ARG_##argtype6 (5) \
00171 __XMMS_CMD_DO_RETVAL_##_rettype() (realfunc ((argtype0)object __XMMS_CMD_PRINT_ARG_##argtype1(0) __XMMS_CMD_PRINT_ARG_##argtype2(1) __XMMS_CMD_PRINT_ARG_##argtype3(2) __XMMS_CMD_PRINT_ARG_##argtype4(3) __XMMS_CMD_PRINT_ARG_##argtype5(4) __XMMS_CMD_PRINT_ARG_##argtype6(5), &arg->error)); \
00172 } \
00173 static const xmms_object_cmd_desc_t __int_xmms_cmd_desc_##cmdid = { __int_xmms_cmd_##cmdid, XMMSV_TYPE_##_rettype, {XMMSV_TYPE_##argtype1, XMMSV_TYPE_##argtype2, XMMSV_TYPE_##argtype3, XMMSV_TYPE_##argtype4, XMMSV_TYPE_##argtype5, XMMSV_TYPE_##argtype6} }
00174 
00175 
00176 #define XMMS_CMD_DEFINE(cmdid, realfunc, argtype0, _rettype, argtype1, argtype2) XMMS_CMD_DEFINE6(cmdid, realfunc, argtype0, _rettype, argtype1, argtype2, NONE, NONE, NONE, NONE)
00177 #define XMMS_CMD_DEFINE3(cmdid, realfunc, argtype0, _rettype, argtype1, argtype2, argtype3) XMMS_CMD_DEFINE6(cmdid, realfunc, argtype0, _rettype, argtype1, argtype2, argtype3, NONE, NONE, NONE)
00178 #define XMMS_CMD_DEFINE4(cmdid, realfunc, argtype0, _rettype, argtype1, argtype2, argtype3, argtype4) XMMS_CMD_DEFINE6(cmdid, realfunc, argtype0, _rettype, argtype1, argtype2, argtype3, argtype4, NONE, NONE)
00179 #define XMMS_CMD_DEFINE5(cmdid, realfunc, argtype0, _rettype, argtype1, argtype2, argtype3, argtype4, argtype5) XMMS_CMD_DEFINE6(cmdid, realfunc, argtype0, _rettype, argtype1, argtype2, argtype3, argtype4, argtype5, NONE)
00180 
00181 #define XMMS_CMD_FUNC(cmdid) &__int_xmms_cmd_desc_##cmdid
00182 
00183 
00184 void __int_xmms_object_unref (xmms_object_t *object);
00185 xmms_object_t *__int_xmms_object_new (gint size, xmms_object_destroy_func_t destfunc);
00186 
00187 #define xmms_object_ref(obj) do { \
00188     if (obj && XMMS_IS_OBJECT (obj)) { \
00189         g_atomic_int_inc (&(XMMS_OBJECT (obj)->ref)); \
00190     } \
00191 } while (0)
00192 
00193 #define xmms_object_unref(obj) do { \
00194     if (obj && XMMS_IS_OBJECT (obj)) { \
00195         __int_xmms_object_unref (XMMS_OBJECT (obj)); \
00196     } \
00197 } while (0)
00198 
00199 #define xmms_object_new(objtype,destroyfunc) (objtype *) __int_xmms_object_new (sizeof (objtype), destroyfunc)
00200 
00201 G_END_DECLS
00202 
00203 #endif /* __XMMS_OBJECT_H__ */