本文整理汇总了C++中EINA_INLIST_GET函数的典型用法代码示例。如果您正苦于以下问题:C++ EINA_INLIST_GET函数的具体用法?C++ EINA_INLIST_GET怎么用?C++ EINA_INLIST_GET使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了EINA_INLIST_GET函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。
示例1: ecore_timer_thaw
/**
* Resumes a frozen (paused) timer.
*
* @param timer The timer to be resumed.
*
* The timer will be resumed from its previous relative position in time. That
* means, if it had X seconds remaining until expire when it was paused, it will
* be started now with those same X seconds remaining to expire again. But
* notice that the interval time won't be touched by this call or by
* ecore_timer_freeze().
*
* @see ecore_timer_freeze()
*/
EAPI void
ecore_timer_thaw(Ecore_Timer *timer)
{
double now;
_ecore_lock();
if (!ECORE_MAGIC_CHECK(timer, ECORE_MAGIC_TIMER))
{
ECORE_MAGIC_FAIL(timer, ECORE_MAGIC_TIMER,
"ecore_timer_thaw");
goto unlock;
}
/* Timer not frozen */
if (!timer->frozen)
goto unlock;
suspended = (Ecore_Timer *)eina_inlist_remove(EINA_INLIST_GET(suspended), EINA_INLIST_GET(timer));
now = ecore_time_get();
_ecore_timer_set(timer, timer->pending + now, timer->in, timer->func, timer->data);
unlock:
_ecore_unlock();
}
开发者ID:roman5566,项目名称:EFL-PS3,代码行数:38,代码来源:ecore_timer.c
示例2: ecore_file_monitor_backend_add
Ecore_File_Monitor *
ecore_file_monitor_backend_add(const char *path,
void (*func) (void *data, Ecore_File_Monitor *em,
Ecore_File_Event event,
const char *path),
void *data)
{
Ecore_File_Monitor *em;
size_t len;
if (!path) return NULL;
if (!func) return NULL;
em = calloc(1, sizeof(Ecore_File_Monitor_Poll));
if (!em) return NULL;
if (!_timer)
_timer = ecore_timer_add(_interval, _ecore_file_monitor_poll_handler, NULL);
else
ecore_timer_interval_set(_timer, ECORE_FILE_INTERVAL_MIN);
em->path = strdup(path);
len = strlen(em->path);
if (em->path[len - 1] == '/' && strcmp(em->path, "/"))
em->path[len - 1] = 0;
em->func = func;
em->data = data;
ECORE_FILE_MONITOR_POLL(em)->mtime = ecore_file_mod_time(em->path);
_monitors = ECORE_FILE_MONITOR(eina_inlist_append(EINA_INLIST_GET(_monitors), EINA_INLIST_GET(em)));
if (ecore_file_exists(em->path))
{
if (ecore_file_is_dir(em->path))
{
/* Check for subdirs */
Eina_List *files;
char *file;
files = ecore_file_ls(em->path);
EINA_LIST_FREE(files, file)
{
Ecore_File *f;
char buf[PATH_MAX];
f = calloc(1, sizeof(Ecore_File));
if (!f)
{
free(file);
continue;
}
snprintf(buf, sizeof(buf), "%s/%s", em->path, file);
f->name = file;
f->mtime = ecore_file_mod_time(buf);
f->is_dir = ecore_file_is_dir(buf);
em->files = (Ecore_File *) eina_inlist_append(EINA_INLIST_GET(em->files), EINA_INLIST_GET(f));
}
}
开发者ID:caivega,项目名称:efl-1,代码行数:60,代码来源:ecore_file_monitor_poll.c
示例3: _ecore_timer_reschedule
static inline void
_ecore_timer_reschedule(Ecore_Timer * timer, double when)
{
if ((timer->delete_me) || (timer->frozen))
return;
timers =
(Ecore_Timer *) eina_inlist_remove(EINA_INLIST_GET(timers),
EINA_INLIST_GET(timer));
/* if the timer would have gone off more than 15 seconds ago,
* assume that the system hung and set the timer to go off
* timer->in from now. this handles system hangs, suspends
* and more, so ecore will only "replay" the timers while
* the system is suspended if it is suspended for less than
* 15 seconds (basically). this also handles if the process
* is stopped in a debugger or IO and other handling gets
* really slow within the main loop.
*/
if ((timer->at + timer->in) < (when - 15.0))
_ecore_timer_set(timer, when + timer->in, timer->in,
timer->func, timer->data);
else
_ecore_timer_set(timer, timer->at + timer->in, timer->in,
timer->func, timer->data);
}
开发者ID:Distrotech,项目名称:gnutls,代码行数:26,代码来源:ecore_timer.c
示例4: eina_matrixsparse_data_idx_get
/**
* Get the exact tile for the given position and zoom.
*
* If the tile was unused then it's removed from the cache.
*
* After usage, please give it back using
* ewk_tile_matrix_tile_put(). If you just want to check if it exists,
* then use ewk_tile_matrix_tile_exact_exists().
*
* @param tm the tile matrix to get tile from.
* @param col the column number.
* @param row the row number.
* @param zoom the exact zoom to use.
*
* @return The tile instance or @c NULL if none is found. If the tile
* was in the unused cache it will be @b removed (thus
* considered used) and one should give it back with
* ewk_tile_matrix_tile_put() afterwards.
*
* @see ewk_tile_matrix_tile_nearest_get()
* @see ewk_tile_matrix_tile_exact_get()
*/
Ewk_Tile *ewk_tile_matrix_tile_exact_get(Ewk_Tile_Matrix *tm, unsigned long col, unsigned int row, float zoom)
{
Ewk_Tile *t, *item, *item_found = NULL;
Eina_Inlist *inl;
t = eina_matrixsparse_data_idx_get(tm->matrix, row, col);
if (!t)
return NULL;
if (t->zoom == zoom)
goto end;
EINA_INLIST_FOREACH(EINA_INLIST_GET(t), item) {
if (item->zoom != zoom)
continue;
item_found = item;
break;
}
if (!item_found)
return NULL;
inl = eina_inlist_promote(EINA_INLIST_GET(t), EINA_INLIST_GET(item_found));
eina_matrixsparse_data_idx_replace(tm->matrix, row, col, inl, NULL);
end:
if (!t->visible) {
if (!ewk_tile_unused_cache_tile_get(tm->tuc, t))
WRN("Ewk_Tile was unused but not in cache? bug!");
}
return t;
}
开发者ID:wufuyue,项目名称:TCL_S820,代码行数:55,代码来源:ewk_tiled_matrix.c
示例5: ecore_exe_free
EAPI void *
ecore_exe_free(Ecore_Exe *exe)
{
void *data;
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
{
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_free");
return NULL;
}
data = exe->data;
if (exe->pre_free_cb)
exe->pre_free_cb(data, exe);
CloseHandle(exe->process2);
CloseHandle(exe->process_thread);
CloseHandle(exe->process);
free(exe->cmd);
_ecore_exe_win32_pipes_close(exe);
exes = (Ecore_Exe *)eina_inlist_remove(EINA_INLIST_GET(exes), EINA_INLIST_GET(exe));
ECORE_MAGIC_SET(exe, ECORE_MAGIC_NONE);
if (exe->tag) free(exe->tag);
free(exe);
return data;
}
开发者ID:Limsik,项目名称:e17,代码行数:28,代码来源:ecore_exe_win32.c
示例6: _evas_cache_engine_image_remove_activ
static void
_evas_cache_engine_image_remove_activ(Evas_Cache_Engine_Image *cache,
Engine_Image_Entry *eim)
{
if (eim->flags.cached)
{
if (eim->flags.dirty)
{
cache->dirty = eina_inlist_remove(cache->dirty, EINA_INLIST_GET(eim));
}
else
if (eim->flags.activ)
{
eina_hash_del(cache->activ, eim->cache_key, eim);
}
else
{
cache->usage -= cache->func.mem_size_get(eim);
eina_hash_del(cache->inactiv, eim->cache_key, eim);
cache->lru = eina_inlist_remove(cache->lru, EINA_INLIST_GET(eim));
}
eim->flags.cached = 0;
eim->flags.dirty = 0;
eim->flags.activ = 0;
}
}
开发者ID:wargio,项目名称:efl,代码行数:26,代码来源:evas_cache_engine_image.c
示例7: _ecore_idle_exiter_call
void
_ecore_idle_exiter_call(void)
{
if (!idle_exiter_current)
{
/* regular main loop, start from head */
idle_exiter_current = idle_exiters;
}
else
{
/* recursive main loop, continue from where we were */
idle_exiter_current =
(Ecore_Idle_Exiter *)EINA_INLIST_GET(idle_exiter_current)->next;
}
while (idle_exiter_current)
{
Ecore_Idle_Exiter *ie = (Ecore_Idle_Exiter *)idle_exiter_current;
if (!ie->delete_me)
{
ie->references++;
if (!_ecore_call_task_cb(ie->func, ie->data))
{
if (!ie->delete_me) _ecore_idle_exiter_del(ie);
}
ie->references--;
}
if (idle_exiter_current) /* may have changed in recursive main loops */
idle_exiter_current =
(Ecore_Idle_Exiter *)EINA_INLIST_GET(idle_exiter_current)->next;
}
if (idle_exiters_delete_me)
{
Ecore_Idle_Exiter *l;
int deleted_idler_exiters_in_use = 0;
for (l = idle_exiters; l; )
{
Ecore_Idle_Exiter *ie = l;
l = (Ecore_Idle_Exiter *)EINA_INLIST_GET(l)->next;
if (ie->delete_me)
{
if (ie->references)
{
deleted_idler_exiters_in_use++;
continue;
}
idle_exiters = (Ecore_Idle_Exiter *)eina_inlist_remove(EINA_INLIST_GET(idle_exiters), EINA_INLIST_GET(ie));
ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE);
ecore_idle_exiter_mp_free(ie);
}
}
if (!deleted_idler_exiters_in_use)
idle_exiters_delete_me = 0;
}
}
开发者ID:Limsik,项目名称:e17,代码行数:58,代码来源:ecore_idle_exiter.c
示例8: _ecore_con_info_slave_free
static void
_ecore_con_info_slave_free(CB_Data *cbdata)
{
info_slaves = (CB_Data *)eina_inlist_remove(EINA_INLIST_GET(info_slaves),
EINA_INLIST_GET(cbdata));
ecore_main_fd_handler_del(cbdata->fdh);
ecore_event_handler_del(cbdata->handler);
close(ecore_main_fd_handler_fd_get(cbdata->fdh));
if (cbdata->data) ecore_con_server_infos_del(cbdata->data, cbdata);
free(cbdata);
}
开发者ID:RomainNaour,项目名称:efl,代码行数:11,代码来源:ecore_con_info.c
示例9: evas_common_tilebuf_free_render_rects
EAPI void
evas_common_tilebuf_free_render_rects(Tilebuf_Rect *rects)
{
while (rects)
{
Tilebuf_Rect *r;
r = rects;
rects = (Tilebuf_Rect *)eina_inlist_remove(EINA_INLIST_GET(rects), EINA_INLIST_GET(r));
free(r);
}
}
开发者ID:nashidau,项目名称:Evas-Next,代码行数:12,代码来源:evas_tiler.c
示例10: ecore_file_monitor_inotify_del
void
ecore_file_monitor_inotify_del(Ecore_File_Monitor *em)
{
int fd;
_monitors = ECORE_FILE_MONITOR(eina_inlist_remove(EINA_INLIST_GET(_monitors), EINA_INLIST_GET(em)));
fd = ecore_main_fd_handler_fd_get(_fdh);
if (ECORE_FILE_MONITOR_INOTIFY(em)->wd)
inotify_rm_watch(fd, ECORE_FILE_MONITOR_INOTIFY(em)->wd);
free(em->path);
free(em);
}
开发者ID:OpenInkpot-archive,项目名称:ecore,代码行数:13,代码来源:ecore_file_monitor_inotify.c
示例11: _ecore_animator_shutdown
void
_ecore_animator_shutdown(void)
{
_end_tick();
while (animators)
{
Ecore_Animator *animator;
animator = animators;
animators = (Ecore_Animator *)eina_inlist_remove(EINA_INLIST_GET(animators), EINA_INLIST_GET(animators));
ECORE_MAGIC_SET(animator, ECORE_MAGIC_NONE);
ecore_animator_mp_free(animator);
}
}
开发者ID:wargio,项目名称:e17,代码行数:14,代码来源:ecore_anim.c
示例12: _comic_chapter_item_new
static Comic_Chapter_Item *
_comic_chapter_item_new(Comic_Chapter *cc)
{
Comic_Chapter_Item *cci;
cci = calloc(1, sizeof(Comic_Chapter_Item));
//DBG("new item: cc %g", cc->number);
_comic_chapter_item_update(cci, cc, EINA_FALSE);
cc->csd->chapters = eina_inlist_remove(cc->csd->chapters, EINA_INLIST_GET(cc));
cc->csd->cs->chapters = eina_inlist_sorted_insert(cc->csd->cs->chapters, EINA_INLIST_GET(cci), (Eina_Compare_Cb)_comic_chapter_item_sort_cb);
cci->chapters = eina_inlist_append(cci->chapters, EINA_INLIST_GET(cc));
cci->chapter_count++;
return cci;
}
开发者ID:zmike,项目名称:emg,代码行数:14,代码来源:comic_chapter_item.c
示例13: comic_chapter_item_chapter_add
Comic_Chapter_Item *
comic_chapter_item_chapter_add(Comic_Chapter *cc, Comic_Chapter_Item *cci)
{
Eina_Bool forward = EINA_TRUE;
//DBG("(cc=%g, cci=%g)", cc->number, cci ? cci->cc->number : 0);
if (!cc->csd->cs->chapters)
return _comic_chapter_item_new(cc);
if (!cci)
{
if (cc->number > cc->csd->cs->total / 2)
{
cci = EINA_INLIST_CONTAINER_GET(cc->csd->cs->chapters->last, Comic_Chapter_Item);
forward = EINA_FALSE;
}
else
cci = EINA_INLIST_CONTAINER_GET(cc->csd->cs->chapters, Comic_Chapter_Item);
}
if (cci->cc->number > cc->number)
forward = EINA_FALSE;
if (forward)
{
//DBG("ITER: FORWARD");
for (; cci; cci = comic_chapter_item_next_get(cci))
{
if (cci->cc->number < cc->number) continue;
cc->csd->chapters = eina_inlist_remove(cc->csd->chapters, EINA_INLIST_GET(cc));
//DBG("INSERT: %g", cci->cc->number);
cci->chapters = eina_inlist_sorted_insert(cci->chapters, EINA_INLIST_GET(cc), (Eina_Compare_Cb)_comic_chapter_sort_cb);
cci->chapter_count++;
_comic_chapter_item_update(cci, cc, EINA_FALSE);
return cci;
}
return _comic_chapter_item_new(cc);
}
//DBG("ITER: BACKWARD");
for (; cci; cci = comic_chapter_item_prev_get(cci))
{
if (cci->cc->number > cc->number) continue;
cc->csd->chapters = eina_inlist_remove(cc->csd->chapters, EINA_INLIST_GET(cc));
//DBG("INSERT: %g", cci->cc->number);
cci->chapters = eina_inlist_sorted_insert(cci->chapters, EINA_INLIST_GET(cc), (Eina_Compare_Cb)_comic_chapter_sort_cb);
cci->chapter_count++;
_comic_chapter_item_update(cci, cc, EINA_FALSE);
return cci;
}
return _comic_chapter_item_new(cc);
}
开发者ID:zmike,项目名称:emg,代码行数:49,代码来源:comic_chapter_item.c
示例14: _do_tick
static Eina_Bool
_do_tick(void)
{
Ecore_Animator *animator;
EINA_INLIST_FOREACH(animators, animator)
{
animator->just_added = EINA_FALSE;
}
EINA_INLIST_FOREACH(animators, animator)
{
if ((!animator->delete_me) &&
(!animator->suspended) &&
(!animator->just_added))
{
if (!_ecore_call_task_cb(animator->func, animator->data))
{
animator->delete_me = EINA_TRUE;
animators_delete_me++;
}
}
else animator->just_added = EINA_FALSE;
}
if (animators_delete_me)
{
Ecore_Animator *l;
for (l = animators; l; )
{
animator = l;
l = (Ecore_Animator *)EINA_INLIST_GET(l)->next;
if (animator->delete_me)
{
animators = (Ecore_Animator *)
eina_inlist_remove(EINA_INLIST_GET(animators),
EINA_INLIST_GET(animator));
ECORE_MAGIC_SET(animator, ECORE_MAGIC_NONE);
ecore_animator_mp_free(animator);
animators_delete_me--;
if (animators_delete_me == 0) break;
}
}
}
if (!animators)
{
_end_tick();
return ECORE_CALLBACK_CANCEL;
}
return ECORE_CALLBACK_RENEW;
}
开发者ID:wargio,项目名称:e17,代码行数:49,代码来源:ecore_anim.c
示例15: esql_mysac_res
static void
esql_mysac_res(Esql_Res *res)
{
MYSAC_ROW *row;
MYSAC_RES *re;
MYSAC *m;
Esql_Row *r;
re = res->backend.res = mysac_get_res(res->e->backend.db);
if (!re) return;
m = res->e->backend.db;
res->desc = esql_module_desc_get(re->nb_cols, (Esql_Module_Setup_Cb)esql_module_setup_cb, res);
mysac_first_row(re);
row = mysac_fetch_row(re);
if (!row) /* must be insert/update/etc */
{
res->affected = m->affected_rows;
res->id = m->insert_id;
return;
}
res->row_count = mysac_num_rows(re);
do
{
r = esql_row_calloc(1);
EINA_SAFETY_ON_NULL_RETURN(r);
r->res = res;
esql_mysac_row_init(r, row);
res->rows = eina_inlist_append(res->rows, EINA_INLIST_GET(r));
} while ((row = mysac_fetch_row(re)));
}
开发者ID:carloslack,项目名称:esskyuehl,代码行数:30,代码来源:esql_mysql_backend.c
示例16: _eina_simple_xml_node_data_new
static Eina_Simple_XML_Node_Data *
_eina_simple_xml_node_data_new(Eina_Simple_XML_Node_Tag *parent, Eina_Simple_XML_Node_Type type, const char *content, unsigned length)
{
Eina_Simple_XML_Node_Data *n;
if (!content) return NULL;
n = malloc(sizeof(*n) + length + 1);
if (!n)
{
ERR("could not allocate memory for node");
return NULL;
}
EINA_MAGIC_SET(&n->base, EINA_MAGIC_SIMPLE_XML_DATA);
n->base.type = type;
n->base.parent = parent;
n->length = length;
memcpy(n->data, content, length);
n->data[length] = '\0';
if (parent)
parent->children = eina_inlist_append
(parent->children, EINA_INLIST_GET(&n->base));
return n;
}
开发者ID:RomainNaour,项目名称:efl,代码行数:29,代码来源:eina_simple_xml_parser.c
示例17: eldbus_signal_handler_match_extra_vset
EAPI Eina_Bool
eldbus_signal_handler_match_extra_vset(Eldbus_Signal_Handler *sh, va_list ap)
{
const char *key = NULL, *read;
DBusError err;
ELDBUS_SIGNAL_HANDLER_CHECK_RETVAL(sh, EINA_FALSE);
dbus_error_init(&err);
dbus_bus_remove_match(sh->conn->dbus_conn,
eina_strbuf_string_get(sh->match), &err);
EINA_SAFETY_ON_TRUE_RETURN_VAL(dbus_error_is_set(&err), EINA_FALSE);
for (read = va_arg(ap, char *); read; read = va_arg(ap, char *))
{
Signal_Argument *arg;
if (!key)
{
key = read;
continue;
}
arg = calloc(1, sizeof(Signal_Argument));
EINA_SAFETY_ON_NULL_GOTO(arg, error);
if (!strncmp(key, ARGX, strlen(ARGX)))
{
int id = atoi(key + strlen(ARGX));
arg->index = (unsigned short) id;
arg->value = eina_stringshare_add(read);
sh->args = eina_inlist_sorted_state_insert(sh->args,
EINA_INLIST_GET(arg),
_sort_arg,
sh->state_args);
_match_append(sh->match, key, read);
}
else
{
ERR("%s not supported", key);
free(arg);
}
key = NULL;
}
dbus_error_init(&err);
dbus_bus_add_match(sh->conn->dbus_conn,
eina_strbuf_string_get(sh->match), &err);
if (!dbus_error_is_set(&err))
return EINA_TRUE;
ERR("Error setting new match.");
return EINA_FALSE;
error:
dbus_error_init(&err);
dbus_bus_add_match(sh->conn->dbus_conn,
eina_strbuf_string_get(sh->match), &err);
if (dbus_error_is_set(&err))
ERR("Error setting partial extra arguments.");
return EINA_FALSE;
}
开发者ID:RomainNaour,项目名称:efl,代码行数:60,代码来源:eldbus_signal_handler.c
示例18: _eina_simple_xml_node_tag_free
void
_eina_simple_xml_node_tag_free(Eina_Simple_XML_Node_Tag *tag)
{
while (tag->children)
{
Eina_Simple_XML_Node *n = EINA_INLIST_CONTAINER_GET
(tag->children, Eina_Simple_XML_Node);
if (n->type == EINA_SIMPLE_XML_NODE_TAG)
_eina_simple_xml_node_tag_free((Eina_Simple_XML_Node_Tag *)n);
else
_eina_simple_xml_node_data_free((Eina_Simple_XML_Node_Data *)n);
}
while (tag->attributes)
{
Eina_Simple_XML_Attribute *a = EINA_INLIST_CONTAINER_GET
(tag->attributes, Eina_Simple_XML_Attribute);
eina_simple_xml_attribute_free(a);
}
if (tag->base.parent)
tag->base.parent->children = eina_inlist_remove
(tag->base.parent->children, EINA_INLIST_GET(&tag->base));
eina_stringshare_del(tag->name);
EINA_MAGIC_SET(&tag->base, EINA_MAGIC_NONE);
eina_mempool_free(_eina_simple_xml_tag_mp, tag);
}
开发者ID:RomainNaour,项目名称:efl,代码行数:28,代码来源:eina_simple_xml_parser.c
示例19: eina_simple_xml_node_tag_new
EAPI Eina_Simple_XML_Node_Tag *
eina_simple_xml_node_tag_new(Eina_Simple_XML_Node_Tag *parent, const char *name)
{
Eina_Simple_XML_Node_Tag *n;
if (!name) return NULL;
n = eina_mempool_malloc(_eina_simple_xml_tag_mp, sizeof(*n));
if (!n)
{
ERR("could not allocate memory for node from mempool");
return NULL;
}
memset(n, 0, sizeof(*n));
EINA_MAGIC_SET(&n->base, EINA_MAGIC_SIMPLE_XML_TAG);
n->base.type = EINA_SIMPLE_XML_NODE_TAG;
n->base.parent = parent;
n->name = eina_stringshare_add(name);
if (parent)
parent->children = eina_inlist_append
(parent->children, EINA_INLIST_GET(&n->base));
return n;
}
开发者ID:RomainNaour,项目名称:efl,代码行数:28,代码来源:eina_simple_xml_parser.c
示例20: eina_simple_xml_attribute_new
EAPI Eina_Simple_XML_Attribute *
eina_simple_xml_attribute_new(Eina_Simple_XML_Node_Tag *parent, const char *key, const char *value)
{
Eina_Simple_XML_Attribute *attr;
if (!key) return NULL;
attr = eina_mempool_malloc(_eina_simple_xml_attribute_mp, sizeof(*attr));
if (!attr)
{
ERR("could not allocate memory for attribute from mempool");
return NULL;
}
EINA_MAGIC_SET(attr, EINA_MAGIC_SIMPLE_XML_ATTRIBUTE);
attr->parent = parent;
attr->key = eina_stringshare_add(key);
attr->value = eina_stringshare_add(value ? value : "");
if (parent)
parent->attributes = eina_inlist_append
(parent->attributes, EINA_INLIST_GET(attr));
return attr;
}
开发者ID:RomainNaour,项目名称:efl,代码行数:25,代码来源:eina_simple_xml_parser.c
注:本文中的EINA_INLIST_GET函数示例整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论