Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-1.1
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-1.1
Commits
7da96633
Commit
7da96633
authored
Jun 02, 2009
by
Pierre d'Herbemont
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
libvlc: Allow event to be dispatched asynchronously.
parent
9b8589f8
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
459 additions
and
107 deletions
+459
-107
src/Makefile.am
src/Makefile.am
+2
-0
src/control/event.c
src/control/event.c
+102
-44
src/control/event_async.c
src/control/event_async.c
+237
-0
src/control/event_internal.h
src/control/event_internal.h
+113
-0
src/control/libvlc_internal.h
src/control/libvlc_internal.h
+5
-63
No files found.
src/Makefile.am
View file @
7da96633
...
...
@@ -439,6 +439,7 @@ SOURCES_libvlc = \
SOURCES_libvlc_control
=
\
control/libvlc_internal.h
\
control/event_internal.h
\
control/media_internal.h
\
control/media_list_internal.h
\
control/media_list_view_internal.h
\
...
...
@@ -450,6 +451,7 @@ SOURCES_libvlc_control = \
control/video.c
\
control/audio.c
\
control/event.c
\
control/event_async.c
\
control/flat_media_list_view.c
\
control/hierarchical_media_list_view.c
\
control/hierarchical_node_media_list_view.c
\
...
...
src/control/event.c
View file @
7da96633
...
...
@@ -22,23 +22,22 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "libvlc_internal.h"
#include <vlc/libvlc.h>
#include <vlc_playlist.h>
#include "libvlc_internal.h"
#include "event_internal.h"
typedef
struct
libvlc_event_listeners_group_t
{
libvlc_event_type_t
event_type
;
vlc_array_t
listeners
;
bool
b_sublistener_removed
;
}
libvlc_event_listeners_group_t
;
/*
* Private functions
*/
static
bool
listeners_are_equal
(
libvlc_event_listener_t
*
listener1
,
libvlc_event_listener_t
*
listener2
)
{
return
listener1
->
event_type
==
listener2
->
event_type
&&
listener1
->
pf_callback
==
listener2
->
pf_callback
&&
listener1
->
p_user_data
==
listener2
->
p_user_data
;
}
static
bool
group_contains_listener
(
libvlc_event_listeners_group_t
*
group
,
libvlc_event_listener_t
*
searched_listener
)
...
...
@@ -75,7 +74,10 @@ libvlc_event_manager_new( void * p_obj, libvlc_instance_t * p_libvlc_inst,
}
p_em
->
p_obj
=
p_obj
;
p_em
->
p_obj
=
p_obj
;
p_em
->
async_event_queue
=
NULL
;
p_em
->
p_libvlc_instance
=
p_libvlc_inst
;
libvlc_retain
(
p_libvlc_inst
);
vlc_array_init
(
&
p_em
->
listeners_groups
);
vlc_mutex_init
(
&
p_em
->
object_lock
);
...
...
@@ -93,6 +95,8 @@ void libvlc_event_manager_release( libvlc_event_manager_t * p_em )
libvlc_event_listeners_group_t
*
p_lg
;
int
i
,
j
;
libvlc_event_async_fini
(
p_em
);
vlc_mutex_destroy
(
&
p_em
->
event_sending_lock
);
vlc_mutex_destroy
(
&
p_em
->
object_lock
);
...
...
@@ -165,7 +169,8 @@ void libvlc_event_send( libvlc_event_manager_t * p_em,
if
(
vlc_array_count
(
&
listeners_group
->
listeners
)
<=
0
)
break
;
/* Cache a copy of the listener to avoid locking issues */
/* Cache a copy of the listener to avoid locking issues,
* and allow that edition of listeners during callbacks will garantee immediate effect. */
i_cached_listeners
=
vlc_array_count
(
&
listeners_group
->
listeners
);
array_listeners_cached
=
malloc
(
sizeof
(
libvlc_event_listener_t
)
*
(
i_cached_listeners
));
if
(
!
array_listeners_cached
)
...
...
@@ -200,22 +205,32 @@ void libvlc_event_send( libvlc_event_manager_t * p_em,
listeners_group
->
b_sublistener_removed
=
false
;
for
(
i
=
0
;
i
<
i_cached_listeners
;
i
++
)
{
if
(
listeners_group
->
b_sublistener_removed
)
if
(
listener_cached
->
is_asynchronous
)
{
/* If a callback was removed, this gets called */
bool
valid_listener
;
vlc_mutex_lock
(
&
p_em
->
object_lock
);
valid_listener
=
group_contains_listener
(
listeners_group
,
listener_cached
);
vlc_mutex_unlock
(
&
p_em
->
object_lock
);
if
(
!
valid_listener
)
/* The listener wants not to block the emitter during event callback */
libvlc_event_async_dispatch
(
p_em
,
listener_cached
,
p_event
);
}
else
{
/* The listener wants to block the emitter during event callback */
listener_cached
->
pf_callback
(
p_event
,
listener_cached
->
p_user_data
);
listener_cached
++
;
if
(
listeners_group
->
b_sublistener_removed
)
{
listener_cached
++
;
continue
;
}
/* If a callback was removed, this gets called */
bool
valid_listener
;
vlc_mutex_lock
(
&
p_em
->
object_lock
);
valid_listener
=
group_contains_listener
(
listeners_group
,
listener_cached
);
vlc_mutex_unlock
(
&
p_em
->
object_lock
);
if
(
!
valid_listener
)
{
listener_cached
++
;
continue
;
}
}
}
listener_cached
->
pf_callback
(
p_event
,
listener_cached
->
p_user_data
);
listener_cached
++
;
}
vlc_mutex_unlock
(
&
p_em
->
event_sending_lock
);
...
...
@@ -287,31 +302,34 @@ const char * libvlc_event_type_name( libvlc_event_type_t event_type )
}
/**************************************************************************
*
libvlc_event_attach (public
) :
*
event_attach (internal
) :
*
* Add a callback for an event.
**************************************************************************/
void
libvlc_event_attach
(
libvlc_event_manager_t
*
p_event_manager
,
libvlc_event_type_t
event_type
,
libvlc_callback_t
pf_callback
,
void
*
p_user_data
,
libvlc_exception_t
*
p_e
)
static
void
event_attach
(
libvlc_event_manager_t
*
p_event_manager
,
libvlc_event_type_t
event_type
,
libvlc_callback_t
pf_callback
,
void
*
p_user_data
,
bool
is_asynchronous
,
libvlc_exception_t
*
p_e
)
{
libvlc_event_listeners_group_t
*
listeners_group
;
libvlc_event_listener_t
*
listener
;
int
i
;
listener
=
malloc
(
sizeof
(
libvlc_event_listener_t
));
if
(
!
listener
)
{
libvlc_exception_raise
(
p_e
,
"No Memory left"
);
return
;
}
listener
->
event_type
=
event_type
;
listener
->
p_user_data
=
p_user_data
;
listener
->
pf_callback
=
pf_callback
;
listener
->
is_asynchronous
=
is_asynchronous
;
vlc_mutex_lock
(
&
p_event_manager
->
object_lock
);
for
(
i
=
0
;
i
<
vlc_array_count
(
&
p_event_manager
->
listeners_groups
);
i
++
)
{
...
...
@@ -324,11 +342,39 @@ void libvlc_event_attach( libvlc_event_manager_t * p_event_manager,
}
}
vlc_mutex_unlock
(
&
p_event_manager
->
object_lock
);
free
(
listener
);
libvlc_exception_raise
(
p_e
,
"This object event manager doesn't know about '%s' events"
,
libvlc_event_type_name
(
event_type
));
"This object event manager doesn't know about '%s' events"
,
libvlc_event_type_name
(
event_type
));
}
/**************************************************************************
* libvlc_event_attach (public) :
*
* Add a callback for an event.
**************************************************************************/
void
libvlc_event_attach
(
libvlc_event_manager_t
*
p_event_manager
,
libvlc_event_type_t
event_type
,
libvlc_callback_t
pf_callback
,
void
*
p_user_data
,
libvlc_exception_t
*
p_e
)
{
event_attach
(
p_event_manager
,
event_type
,
pf_callback
,
p_user_data
,
false
/* synchronous */
,
p_e
);
}
/**************************************************************************
* libvlc_event_attach (public) :
*
* Add a callback for an event.
**************************************************************************/
void
libvlc_event_attach_async
(
libvlc_event_manager_t
*
p_event_manager
,
libvlc_event_type_t
event_type
,
libvlc_callback_t
pf_callback
,
void
*
p_user_data
,
libvlc_exception_t
*
p_e
)
{
event_attach
(
p_event_manager
,
event_type
,
pf_callback
,
p_user_data
,
true
/* asynchronous */
,
p_e
);
}
/**************************************************************************
...
...
@@ -345,7 +391,8 @@ void libvlc_event_detach( libvlc_event_manager_t *p_event_manager,
libvlc_event_listeners_group_t
*
listeners_group
;
libvlc_event_listener_t
*
listener
;
int
i
,
j
;
bool
found
=
false
;
vlc_mutex_lock
(
&
p_event_manager
->
event_sending_lock
);
vlc_mutex_lock
(
&
p_event_manager
->
object_lock
);
for
(
i
=
0
;
i
<
vlc_array_count
(
&
p_event_manager
->
listeners_groups
);
i
++
)
...
...
@@ -368,9 +415,8 @@ void libvlc_event_detach( libvlc_event_manager_t *p_event_manager,
free
(
listener
);
vlc_array_remove
(
&
listeners_group
->
listeners
,
j
);
vlc_mutex_unlock
(
&
p_event_manager
->
object_lock
);
vlc_mutex_unlock
(
&
p_event_manager
->
event_sending_lock
);
return
;
found
=
true
;
break
;
}
}
}
...
...
@@ -378,7 +424,19 @@ void libvlc_event_detach( libvlc_event_manager_t *p_event_manager,
vlc_mutex_unlock
(
&
p_event_manager
->
object_lock
);
vlc_mutex_unlock
(
&
p_event_manager
->
event_sending_lock
);
libvlc_exception_raise
(
p_e
,
"This object event manager doesn't know about '%s,%p,%p' event observer"
,
libvlc_event_type_name
(
event_type
),
pf_callback
,
p_user_data
);
/* Now make sure any pending async event won't get fired after that point */
libvlc_event_listener_t
listener_to_remove
;
listener_to_remove
.
event_type
=
event_type
;
listener_to_remove
.
pf_callback
=
pf_callback
;
listener_to_remove
.
p_user_data
=
p_user_data
;
listener_to_remove
.
is_asynchronous
=
true
;
libvlc_event_async_ensure_listener_removal
(
p_event_manager
,
&
listener_to_remove
);
if
(
!
found
)
{
libvlc_exception_raise
(
p_e
,
"This object event manager doesn't know about '%s,%p,%p' event observer"
,
libvlc_event_type_name
(
event_type
),
pf_callback
,
p_user_data
);
}
}
src/control/event_async.c
0 → 100644
View file @
7da96633
/*****************************************************************************
* event.c: New libvlc event control API
*****************************************************************************
* Copyright (C) 2007 the VideoLAN team
* $Id $
*
* Authors: Filippo Carone <filippo@carone.org>
* Pierre d'Herbemont <pdherbemont # videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include <vlc/libvlc.h>
#include "libvlc_internal.h"
#include "event_internal.h"
struct
queue_elmt
{
libvlc_event_listener_t
listener
;
libvlc_event_t
event
;
struct
queue_elmt
*
next
;
};
struct
libvlc_event_async_queue
{
struct
queue_elmt
*
elements
;
vlc_mutex_t
lock
;
vlc_cond_t
signal
;
vlc_thread_t
thread
;
};
/*
* Utilities
*/
static
void
*
event_async_loop
(
void
*
arg
);
static
inline
struct
libvlc_event_async_queue
*
queue
(
libvlc_event_manager_t
*
p_em
)
{
return
p_em
->
async_event_queue
;
}
static
inline
bool
is_queue_initialized
(
libvlc_event_manager_t
*
p_em
)
{
return
queue
(
p_em
)
!=
NULL
;
}
/* Lock must be held */
static
void
push
(
libvlc_event_manager_t
*
p_em
,
libvlc_event_listener_t
*
listener
,
libvlc_event_t
*
event
)
{
#ifndef NDEBUG
static
const
long
MaxQueuedItem
=
300000
;
long
count
=
0
;
#endif
struct
queue_elmt
*
elmt
=
malloc
(
sizeof
(
struct
queue_elmt
));
elmt
->
listener
=
*
listener
;
elmt
->
event
=
*
event
;
elmt
->
next
=
NULL
;
/* Append to the end of the queue */
struct
queue_elmt
*
iter
=
queue
(
p_em
)
->
elements
;
if
(
!
iter
)
{
queue
(
p_em
)
->
elements
=
elmt
;
return
;
}
while
(
iter
->
next
)
{
iter
=
iter
->
next
;
#ifndef NDEBUG
if
(
count
++
>
MaxQueuedItem
)
{
fprintf
(
stderr
,
"Warning: libvlc event overflow.
\n
"
);
abort
();
}
#endif
}
iter
->
next
=
elmt
;
}
/* Lock must be held */
static
bool
pop
(
libvlc_event_manager_t
*
p_em
,
libvlc_event_listener_t
*
listener
,
libvlc_event_t
*
event
)
{
if
(
!
queue
(
p_em
)
->
elements
)
return
false
;
/* No elements */
*
listener
=
queue
(
p_em
)
->
elements
->
listener
;
*
event
=
queue
(
p_em
)
->
elements
->
event
;
struct
queue_elmt
*
elmt
=
queue
(
p_em
)
->
elements
;
queue
(
p_em
)
->
elements
=
elmt
->
next
;
free
(
elmt
);
return
true
;
}
/* Lock must be held */
static
void
pop_listener
(
libvlc_event_manager_t
*
p_em
,
libvlc_event_listener_t
*
listener
)
{
struct
queue_elmt
*
iter
=
queue
(
p_em
)
->
elements
;
struct
queue_elmt
*
prev
=
NULL
;
while
(
iter
)
{
if
(
listeners_are_equal
(
&
iter
->
listener
,
listener
))
{
if
(
!
prev
)
queue
(
p_em
)
->
elements
=
iter
->
next
;
else
prev
->
next
=
iter
->
next
;
free
(
iter
);
}
prev
=
iter
;
iter
=
iter
->
next
;
}
}
/**************************************************************************
* libvlc_event_async_fini (internal) :
*
* Destroy what might have been created by.
**************************************************************************/
void
libvlc_event_async_fini
(
libvlc_event_manager_t
*
p_em
)
{
if
(
!
is_queue_initialized
(
p_em
))
return
;
vlc_thread_t
thread
=
queue
(
p_em
)
->
thread
;
if
(
thread
)
{
vlc_cancel
(
thread
);
vlc_join
(
thread
,
NULL
);
}
vlc_mutex_destroy
(
&
queue
(
p_em
)
->
lock
);
vlc_cond_destroy
(
&
queue
(
p_em
)
->
signal
);
struct
queue_elmt
*
iter
=
queue
(
p_em
)
->
elements
;
while
(
iter
)
{
struct
queue_elmt
*
elemt_to_delete
=
iter
;
iter
=
iter
->
next
;
free
(
elemt_to_delete
);
}
free
(
queue
(
p_em
));
}
/**************************************************************************
* libvlc_event_async_init (private) :
*
* Destroy what might have been created by.
**************************************************************************/
static
void
libvlc_event_async_init
(
libvlc_event_manager_t
*
p_em
)
{
p_em
->
async_event_queue
=
calloc
(
1
,
sizeof
(
struct
libvlc_event_async_queue
));
int
error
=
vlc_clone
(
&
queue
(
p_em
)
->
thread
,
event_async_loop
,
p_em
,
VLC_THREAD_PRIORITY_LOW
);
if
(
error
)
{
free
(
p_em
->
async_event_queue
);
p_em
->
async_event_queue
=
NULL
;
return
;
}
vlc_mutex_init_recursive
(
&
queue
(
p_em
)
->
lock
);
// Beware, this is re-entrant
vlc_cond_init
(
&
queue
(
p_em
)
->
signal
);
}
/**************************************************************************
* libvlc_event_async_ensure_listener_removal (internal) :
*
* Make sure no more message will be issued to the listener.
**************************************************************************/
void
libvlc_event_async_ensure_listener_removal
(
libvlc_event_manager_t
*
p_em
,
libvlc_event_listener_t
*
listener
)
{
if
(
!
is_queue_initialized
(
p_em
))
return
;
vlc_mutex_lock
(
&
queue
(
p_em
)
->
lock
);
pop_listener
(
p_em
,
listener
);
vlc_mutex_unlock
(
&
queue
(
p_em
)
->
lock
);
}
/**************************************************************************
* libvlc_event_async_dispatch (internal) :
*
* Send an event in an asynchronous way.
**************************************************************************/
void
libvlc_event_async_dispatch
(
libvlc_event_manager_t
*
p_em
,
libvlc_event_listener_t
*
listener
,
libvlc_event_t
*
event
)
{
// We do a lazy init here, to prevent constructing the thread when not needed.
vlc_mutex_lock
(
&
p_em
->
object_lock
);
if
(
!
queue
(
p_em
))
libvlc_event_async_init
(
p_em
);
vlc_mutex_unlock
(
&
p_em
->
object_lock
);
vlc_mutex_lock
(
&
queue
(
p_em
)
->
lock
);
push
(
p_em
,
listener
,
event
);
vlc_cond_signal
(
&
queue
(
p_em
)
->
signal
);
vlc_mutex_unlock
(
&
queue
(
p_em
)
->
lock
);
}
/**************************************************************************
* event_async_loop (private) :
*
* Send queued events.
**************************************************************************/
static
void
*
event_async_loop
(
void
*
arg
)
{
libvlc_event_manager_t
*
p_em
=
arg
;
libvlc_event_listener_t
listener
;
libvlc_event_t
event
;
vlc_mutex_lock
(
&
queue
(
p_em
)
->
lock
);
vlc_cleanup_push
(
vlc_cleanup_lock
,
&
queue
(
p_em
)
->
lock
);
while
(
true
)
{
int
has_listener
=
pop
(
p_em
,
&
listener
,
&
event
);
if
(
has_listener
)
listener
.
pf_callback
(
&
event
,
listener
.
p_user_data
);
// This might edit the queue, ->lock is recursive
else
vlc_cond_wait
(
&
queue
(
p_em
)
->
signal
,
&
queue
(
p_em
)
->
lock
);
}
vlc_cleanup_pop
();
vlc_mutex_unlock
(
&
queue
(
p_em
)
->
lock
);
return
NULL
;
}
src/control/event_internal.h
0 → 100644
View file @
7da96633
/*****************************************************************************
* libvlc_internal.h : Definition of opaque structures for libvlc exported API
* Also contains some internal utility functions
*****************************************************************************
* Copyright (C) 2005-2009 the VideoLAN team
* $Id$
*
* Authors: Clément Stenac <zorglub@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef _LIBVLC_EVENT_H
#define _LIBVLC_EVENT_H 1
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc/libvlc_structures.h>
#include <vlc/libvlc.h>
#include <vlc/libvlc_events.h>
#include <vlc_common.h>
/*
* Event Handling
*/
/* Example usage
*
* struct libvlc_cool_object_t
* {
* ...
* libvlc_event_manager_t * p_event_manager;
* ...
* }
*
* libvlc_my_cool_object_new()
* {
* ...
* p_self->p_event_manager = libvlc_event_manager_new( p_self,
* p_self->p_libvlc_instance, p_e);
* libvlc_event_manager_register_event_type(p_self->p_event_manager,
* libvlc_MyCoolObjectDidSomething, p_e)
* ...
* }
*
* libvlc_my_cool_object_release()
* {
* ...
* libvlc_event_manager_release( p_self->p_event_manager );
* ...
* }
*
* libvlc_my_cool_object_do_something()
* {
* ...
* libvlc_event_t event;
* event.type = libvlc_MyCoolObjectDidSomething;
* event.u.my_cool_object_did_something.what_it_did = kSomething;
* libvlc_event_send( p_self->p_event_manager, &event );
* }
* */
typedef
struct
libvlc_event_listener_t
{
libvlc_event_type_t
event_type
;
void
*
p_user_data
;
libvlc_callback_t
pf_callback
;
bool
is_asynchronous
;
}
libvlc_event_listener_t
;
typedef
struct
libvlc_event_manager_t
{
void
*
p_obj
;
struct
libvlc_instance_t
*
p_libvlc_instance
;
vlc_array_t
listeners_groups
;
vlc_mutex_t
object_lock
;
vlc_mutex_t
event_sending_lock
;
struct
libvlc_event_async_queue
*
async_event_queue
;
}
libvlc_event_sender_t
;
static
inline
bool
listeners_are_equal
(
libvlc_event_listener_t
*
listener1
,
libvlc_event_listener_t
*
listener2
)
{
return
listener1
->
event_type
==
listener2
->
event_type
&&
listener1
->
pf_callback
==
listener2
->
pf_callback
&&
listener1
->
p_user_data
==
listener2
->
p_user_data
&&
listener1
->
is_asynchronous
==
listener2
->
is_asynchronous
;
}
/* event_async.c */
void
libvlc_event_async_fini
(
libvlc_event_manager_t
*
p_em
);
void
libvlc_event_async_dispatch
(
libvlc_event_manager_t
*
p_em
,
libvlc_event_listener_t
*
listener
,
libvlc_event_t
*
event
);
void
libvlc_event_async_ensure_listener_removal
(
libvlc_event_manager_t
*
p_em
,
libvlc_event_listener_t
*
listener
);
#endif
src/control/libvlc_internal.h
View file @
7da96633
...
...
@@ -71,69 +71,6 @@ struct libvlc_instance_t
};
/*
* Event Handling
*/
/* Example usage
*
* struct libvlc_cool_object_t
* {
* ...
* libvlc_event_manager_t * p_event_manager;
* ...
* }
*
* libvlc_my_cool_object_new()
* {
* ...
* p_self->p_event_manager = libvlc_event_manager_new( p_self,
* p_self->p_libvlc_instance, p_e);
* libvlc_event_manager_register_event_type(p_self->p_event_manager,
* libvlc_MyCoolObjectDidSomething, p_e)
* ...
* }
*
* libvlc_my_cool_object_release()
* {
* ...
* libvlc_event_manager_release( p_self->p_event_manager );
* ...
* }
*
* libvlc_my_cool_object_do_something()
* {
* ...
* libvlc_event_t event;
* event.type = libvlc_MyCoolObjectDidSomething;
* event.u.my_cool_object_did_something.what_it_did = kSomething;
* libvlc_event_send( p_self->p_event_manager, &event );
* }
* */
typedef
struct
libvlc_event_listener_t
{
libvlc_event_type_t
event_type
;
void
*
p_user_data
;
libvlc_callback_t
pf_callback
;
}
libvlc_event_listener_t
;
typedef
struct
libvlc_event_listeners_group_t
{
libvlc_event_type_t
event_type
;
vlc_array_t
listeners
;
bool
b_sublistener_removed
;
}
libvlc_event_listeners_group_t
;
typedef
struct
libvlc_event_manager_t
{
void
*
p_obj
;
struct
libvlc_instance_t
*
p_libvlc_instance
;
vlc_array_t
listeners_groups
;
vlc_mutex_t
object_lock
;
vlc_mutex_t
event_sending_lock
;
}
libvlc_event_sender_t
;
/***************************************************************************
* Other internal functions
***************************************************************************/
...
...
@@ -155,6 +92,11 @@ void libvlc_event_send(
libvlc_event_manager_t
*
p_em
,
libvlc_event_t
*
p_event
);
void
libvlc_event_attach_async
(
libvlc_event_manager_t
*
p_event_manager
,
libvlc_event_type_t
event_type
,
libvlc_callback_t
pf_callback
,
void
*
p_user_data
,
libvlc_exception_t
*
p_e
);
/* Exception shorcuts */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment