2 * mlt_events.h -- event handling
3 * Copyright (C) 2004-2005 Ushodaya Enterprises Limited
4 * Author: Charles Yates <charles.yates@pandora.be>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 #include "mlt_properties.h"
26 #include "mlt_events.h"
28 /** Memory leak checks.
31 //#define _MLT_EVENT_CHECKS_
33 #ifdef _MLT_EVENT_CHECKS_
34 static int events_created = 0;
35 static int events_destroyed = 0;
38 struct mlt_events_struct
44 typedef struct mlt_events_struct *mlt_events;
46 struct mlt_event_struct
51 mlt_listener listener;
55 /** Increment the reference count on this event.
58 void mlt_event_inc_ref( mlt_event this )
60 if ( this != NULL && this->owner != NULL )
64 /** Increment the block count on this event.
67 void mlt_event_block( mlt_event this )
69 if ( this != NULL && this->owner != NULL )
73 /** Decrement the block count on this event.
76 void mlt_event_unblock( mlt_event this )
78 if ( this != NULL && this->owner != NULL )
85 void mlt_event_close( mlt_event this )
87 if ( this != NULL && this->owner != NULL )
89 if ( -- this->ref_count == 1 )
91 if ( this->ref_count <= 0 )
93 #ifdef _MLT_EVENT_CHECKS_
95 fprintf( stderr, "Events created %d, destroyed %d\n", events_created, events_destroyed );
102 /** Forward declaration to private functions.
105 static mlt_events mlt_events_fetch( mlt_properties );
106 static void mlt_events_store( mlt_properties, mlt_events );
107 static void mlt_events_close( mlt_events );
109 /** Initialise the events structure.
112 void mlt_events_init( mlt_properties this )
114 mlt_events events = mlt_events_fetch( this );
115 if ( events == NULL )
117 events = malloc( sizeof( struct mlt_events_struct ) );
118 events->list = mlt_properties_new( );
119 mlt_events_store( this, events );
123 /** Register an event and transmitter.
126 int mlt_events_register( mlt_properties this, char *id, mlt_transmitter transmitter )
129 mlt_events events = mlt_events_fetch( this );
130 if ( events != NULL )
132 mlt_properties list = events->list;
134 error = mlt_properties_set_data( list, id, transmitter, 0, NULL, NULL );
135 sprintf( temp, "list:%s", id );
136 if ( mlt_properties_get_data( list, temp, NULL ) == NULL )
137 mlt_properties_set_data( list, temp, mlt_properties_new( ), 0, ( mlt_destructor )mlt_properties_close, NULL );
145 void mlt_events_fire( mlt_properties this, char *id, ... )
147 mlt_events events = mlt_events_fetch( this );
148 if ( events != NULL )
153 mlt_properties list = events->list;
154 mlt_properties listeners = NULL;
156 mlt_transmitter transmitter = mlt_properties_get_data( list, id, NULL );
157 sprintf( temp, "list:%s", id );
158 listeners = mlt_properties_get_data( list, temp, NULL );
160 va_start( alist, id );
162 args[ i ] = va_arg( alist, void * );
163 while( args[ i ++ ] != NULL );
166 if ( listeners != NULL )
168 for ( i = 0; i < mlt_properties_count( listeners ); i ++ )
170 mlt_event event = mlt_properties_get_data_at( listeners, i, NULL );
171 if ( event != NULL && event->owner != NULL && event->block_count == 0 )
173 if ( transmitter != NULL )
174 transmitter( event->listener, event->owner, event->service, args );
176 event->listener( event->owner, event->service );
183 /** Register a listener.
186 mlt_event mlt_events_listen( mlt_properties this, void *service, char *id, mlt_listener listener )
188 mlt_event event = NULL;
189 mlt_events events = mlt_events_fetch( this );
190 if ( events != NULL )
192 mlt_properties list = events->list;
193 mlt_properties listeners = NULL;
195 sprintf( temp, "list:%s", id );
196 listeners = mlt_properties_get_data( list, temp, NULL );
197 if ( listeners != NULL )
201 for ( i = 0; event == NULL && i < mlt_properties_count( listeners ); i ++ )
203 mlt_event entry = mlt_properties_get_data_at( listeners, i, NULL );
204 if ( entry != NULL && entry->owner != NULL )
206 if ( entry->service == service && entry->listener == listener )
209 else if ( ( entry == NULL || entry->owner == NULL ) && first_null == -1 )
217 event = malloc( sizeof( struct mlt_event_struct ) );
220 #ifdef _MLT_EVENT_CHECKS_
223 sprintf( temp, "%d", first_null == -1 ? mlt_properties_count( listeners ) : first_null );
224 event->owner = events;
225 event->ref_count = 0;
226 event->block_count = 0;
227 event->listener = listener;
228 event->service = service;
229 mlt_properties_set_data( listeners, temp, event, 0, ( mlt_destructor )mlt_event_close, NULL );
234 mlt_event_inc_ref( event );
240 /** Block all events for a given service.
243 void mlt_events_block( mlt_properties this, void *service )
245 mlt_events events = mlt_events_fetch( this );
246 if ( events != NULL )
249 mlt_properties list = events->list;
250 for ( j = 0; j < mlt_properties_count( list ); j ++ )
252 char *temp = mlt_properties_get_name( list, j );
253 if ( !strncmp( temp, "list:", 5 ) )
255 mlt_properties listeners = mlt_properties_get_data( list, temp, NULL );
256 for ( i = 0; i < mlt_properties_count( listeners ); i ++ )
258 mlt_event entry = mlt_properties_get_data_at( listeners, i, NULL );
259 if ( entry != NULL && entry->service == service )
260 mlt_event_block( entry );
267 /** Unblock all events for a given service.
270 void mlt_events_unblock( mlt_properties this, void *service )
272 mlt_events events = mlt_events_fetch( this );
273 if ( events != NULL )
276 mlt_properties list = events->list;
277 for ( j = 0; j < mlt_properties_count( list ); j ++ )
279 char *temp = mlt_properties_get_name( list, j );
280 if ( !strncmp( temp, "list:", 5 ) )
282 mlt_properties listeners = mlt_properties_get_data( list, temp, NULL );
283 for ( i = 0; i < mlt_properties_count( listeners ); i ++ )
285 mlt_event entry = mlt_properties_get_data_at( listeners, i, NULL );
286 if ( entry != NULL && entry->service == service )
287 mlt_event_unblock( entry );
294 /** Disconnect all events for a given service.
297 void mlt_events_disconnect( mlt_properties this, void *service )
299 mlt_events events = mlt_events_fetch( this );
300 if ( events != NULL )
303 mlt_properties list = events->list;
304 for ( j = 0; j < mlt_properties_count( list ); j ++ )
306 char *temp = mlt_properties_get_name( list, j );
307 if ( !strncmp( temp, "list:", 5 ) )
309 mlt_properties listeners = mlt_properties_get_data( list, temp, NULL );
310 for ( i = 0; i < mlt_properties_count( listeners ); i ++ )
312 mlt_event entry = mlt_properties_get_data_at( listeners, i, NULL );
313 char *name = mlt_properties_get_name( listeners, i );
314 if ( entry != NULL && entry->service == service )
315 mlt_properties_set_data( listeners, name, NULL, 0, NULL, NULL );
322 /** Fetch the events object.
325 static mlt_events mlt_events_fetch( mlt_properties this )
327 mlt_events events = NULL;
329 events = mlt_properties_get_data( this, "_events", NULL );
333 /** Store the events object.
336 static void mlt_events_store( mlt_properties this, mlt_events events )
338 if ( this != NULL && events != NULL )
339 mlt_properties_set_data( this, "_events", events, 0, ( mlt_destructor )mlt_events_close, NULL );
342 /** Close the events object.
345 static void mlt_events_close( mlt_events events )
347 if ( events != NULL )
349 mlt_properties_close( events->list );