X-Git-Url: http://research.m1stereo.tv/gitweb?a=blobdiff_plain;f=src%2Fframework%2Fmlt_events.c;fp=src%2Fframework%2Fmlt_events.c;h=0000000000000000000000000000000000000000;hb=17b5a97b9bbe00b442a58a5065498e67b497af09;hp=5c841901ed215296a9d809d1fc2b71f2994dc28d;hpb=f4963a6aa07644399b273b5d2b1f9299c9047414;p=melted diff --git a/src/framework/mlt_events.c b/src/framework/mlt_events.c deleted file mode 100644 index 5c84190..0000000 --- a/src/framework/mlt_events.c +++ /dev/null @@ -1,503 +0,0 @@ -/** - * \file mlt_events.c - * \brief event handling - * \see mlt_events_struct - * - * Copyright (C) 2004-2009 Ushodaya Enterprises Limited - * \author Charles Yates - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include - -#include "mlt_properties.h" -#include "mlt_events.h" - -/* Memory leak checks. */ - -#undef _MLT_EVENT_CHECKS_ - -#ifdef _MLT_EVENT_CHECKS_ -static int events_created = 0; -static int events_destroyed = 0; -#endif - -/** \brief Events class - * - * Events provide messages and notifications between services and the application. - * A service can register an event and fire/send it upon certain conditions or times. - * Likewise, a service or an application can listen/receive specific events on specific - * services. - */ - -struct mlt_events_struct -{ - mlt_properties owner; - mlt_properties list; -}; - -typedef struct mlt_events_struct *mlt_events; - -/** \brief Event class - * - */ - -struct mlt_event_struct -{ - mlt_events owner; - int ref_count; - int block_count; - mlt_listener listener; - void *service; -}; - -/** Increment the reference count on this event. - * - * \public \memberof mlt_event_struct - * \param this an event - */ - -void mlt_event_inc_ref( mlt_event this ) -{ - if ( this != NULL ) - this->ref_count ++; -} - -/** Increment the block count on this event. - * - * \public \memberof mlt_event_struct - * \param this an event - */ - -void mlt_event_block( mlt_event this ) -{ - if ( this != NULL && this->owner != NULL ) - this->block_count ++; -} - -/** Decrement the block count on this event. - * - * \public \memberof mlt_event_struct - * \param this an event - */ - -void mlt_event_unblock( mlt_event this ) -{ - if ( this != NULL && this->owner != NULL ) - this->block_count --; -} - -/** Close this event. - * - * \public \memberof mlt_event_struct - * \param this an event - */ - -void mlt_event_close( mlt_event this ) -{ - if ( this != NULL ) - { - if ( -- this->ref_count == 1 ) - this->owner = NULL; - if ( this->ref_count <= 0 ) - { -#ifdef _MLT_EVENT_CHECKS_ - mlt_log( NULL, MLT_LOG_DEBUG, "Events created %d, destroyed %d\n", events_created, ++events_destroyed ); -#endif - free( this ); - } - } -} - -/* Forward declaration to private functions. -*/ - -static mlt_events mlt_events_fetch( mlt_properties ); -static void mlt_events_store( mlt_properties, mlt_events ); -static void mlt_events_close( mlt_events ); - -/** Initialise the events structure. - * - * \public \memberof mlt_events_struct - * \param this a properties list - */ - -void mlt_events_init( mlt_properties this ) -{ - mlt_events events = mlt_events_fetch( this ); - if ( events == NULL ) - { - events = malloc( sizeof( struct mlt_events_struct ) ); - events->list = mlt_properties_new( ); - mlt_events_store( this, events ); - } -} - -/** Register an event and transmitter. - * - * \public \memberof mlt_events_struct - * \param this a properties list - * \param id the name of an event - * \param transmitter the callback function to send an event message - * \return true if there was an error - */ - -int mlt_events_register( mlt_properties this, const char *id, mlt_transmitter transmitter ) -{ - int error = 1; - mlt_events events = mlt_events_fetch( this ); - if ( events != NULL ) - { - mlt_properties list = events->list; - char temp[ 128 ]; - error = mlt_properties_set_data( list, id, transmitter, 0, NULL, NULL ); - sprintf( temp, "list:%s", id ); - if ( mlt_properties_get_data( list, temp, NULL ) == NULL ) - mlt_properties_set_data( list, temp, mlt_properties_new( ), 0, ( mlt_destructor )mlt_properties_close, NULL ); - } - return error; -} - -/** Fire an event. - * - * This takes a variable number of arguments to supply to the listener. - - * \public \memberof mlt_events_struct - * \param this a properties list - * \param id the name of an event - */ - -void mlt_events_fire( mlt_properties this, const char *id, ... ) -{ - mlt_events events = mlt_events_fetch( this ); - if ( events != NULL ) - { - int i = 0; - va_list alist; - void *args[ 10 ]; - mlt_properties list = events->list; - mlt_properties listeners = NULL; - char temp[ 128 ]; - mlt_transmitter transmitter = mlt_properties_get_data( list, id, NULL ); - sprintf( temp, "list:%s", id ); - listeners = mlt_properties_get_data( list, temp, NULL ); - - va_start( alist, id ); - do - args[ i ] = va_arg( alist, void * ); - while( args[ i ++ ] != NULL ); - va_end( alist ); - - if ( listeners != NULL ) - { - for ( i = 0; i < mlt_properties_count( listeners ); i ++ ) - { - mlt_event event = mlt_properties_get_data_at( listeners, i, NULL ); - if ( event != NULL && event->owner != NULL && event->block_count == 0 ) - { - if ( transmitter != NULL ) - transmitter( event->listener, event->owner, event->service, args ); - else - event->listener( event->owner, event->service ); - } - } - } - } -} - -/** Register a listener. - * - * \public \memberof mlt_events_struct - * \param this a properties list - * \param service an opaque pointer - * \param id the name of the event to listen for - * \param listener the callback to receive an event message - * \return - */ - -mlt_event mlt_events_listen( mlt_properties this, void *service, const char *id, mlt_listener listener ) -{ - mlt_event event = NULL; - mlt_events events = mlt_events_fetch( this ); - if ( events != NULL ) - { - mlt_properties list = events->list; - mlt_properties listeners = NULL; - char temp[ 128 ]; - sprintf( temp, "list:%s", id ); - listeners = mlt_properties_get_data( list, temp, NULL ); - if ( listeners != NULL ) - { - int first_null = -1; - int i = 0; - for ( i = 0; event == NULL && i < mlt_properties_count( listeners ); i ++ ) - { - mlt_event entry = mlt_properties_get_data_at( listeners, i, NULL ); - if ( entry != NULL && entry->owner != NULL ) - { - if ( entry->service == service && entry->listener == listener ) - event = entry; - } - else if ( ( entry == NULL || entry->owner == NULL ) && first_null == -1 ) - { - first_null = i; - } - } - - if ( event == NULL ) - { - event = malloc( sizeof( struct mlt_event_struct ) ); - if ( event != NULL ) - { -#ifdef _MLT_EVENT_CHECKS_ - events_created ++; -#endif - sprintf( temp, "%d", first_null == -1 ? mlt_properties_count( listeners ) : first_null ); - event->owner = events; - event->ref_count = 0; - event->block_count = 0; - event->listener = listener; - event->service = service; - mlt_properties_set_data( listeners, temp, event, 0, ( mlt_destructor )mlt_event_close, NULL ); - mlt_event_inc_ref( event ); - } - } - - } - } - return event; -} - -/** Block all events for a given service. - * - * \public \memberof mlt_events_struct - * \param this a properties list - * \param service an opaque pointer - */ - -void mlt_events_block( mlt_properties this, void *service ) -{ - mlt_events events = mlt_events_fetch( this ); - if ( events != NULL ) - { - int i = 0, j = 0; - mlt_properties list = events->list; - for ( j = 0; j < mlt_properties_count( list ); j ++ ) - { - char *temp = mlt_properties_get_name( list, j ); - if ( !strncmp( temp, "list:", 5 ) ) - { - mlt_properties listeners = mlt_properties_get_data( list, temp, NULL ); - for ( i = 0; i < mlt_properties_count( listeners ); i ++ ) - { - mlt_event entry = mlt_properties_get_data_at( listeners, i, NULL ); - if ( entry != NULL && entry->service == service ) - mlt_event_block( entry ); - } - } - } - } -} - -/** Unblock all events for a given service. - * - * \public \memberof mlt_events_struct - * \param this a properties list - * \param service an opaque pointer - */ - -void mlt_events_unblock( mlt_properties this, void *service ) -{ - mlt_events events = mlt_events_fetch( this ); - if ( events != NULL ) - { - int i = 0, j = 0; - mlt_properties list = events->list; - for ( j = 0; j < mlt_properties_count( list ); j ++ ) - { - char *temp = mlt_properties_get_name( list, j ); - if ( !strncmp( temp, "list:", 5 ) ) - { - mlt_properties listeners = mlt_properties_get_data( list, temp, NULL ); - for ( i = 0; i < mlt_properties_count( listeners ); i ++ ) - { - mlt_event entry = mlt_properties_get_data_at( listeners, i, NULL ); - if ( entry != NULL && entry->service == service ) - mlt_event_unblock( entry ); - } - } - } - } -} - -/** Disconnect all events for a given service. - * - * \public \memberof mlt_events_struct - * \param this a properties list - * \param service an opaque pointer - */ - -void mlt_events_disconnect( mlt_properties this, void *service ) -{ - mlt_events events = mlt_events_fetch( this ); - if ( events != NULL ) - { - int i = 0, j = 0; - mlt_properties list = events->list; - for ( j = 0; j < mlt_properties_count( list ); j ++ ) - { - char *temp = mlt_properties_get_name( list, j ); - if ( !strncmp( temp, "list:", 5 ) ) - { - mlt_properties listeners = mlt_properties_get_data( list, temp, NULL ); - for ( i = 0; i < mlt_properties_count( listeners ); i ++ ) - { - mlt_event entry = mlt_properties_get_data_at( listeners, i, NULL ); - char *name = mlt_properties_get_name( listeners, i ); - if ( entry != NULL && entry->service == service ) - mlt_properties_set_data( listeners, name, NULL, 0, NULL, NULL ); - } - } - } - } -} - -/** \brief private to mlt_events_struct, used by mlt_events_wait_for() */ - -typedef struct -{ - int done; - pthread_cond_t cond; - pthread_mutex_t mutex; -} -condition_pair; - -/** The event listener callback for the wait functions. - * - * \private \memberof mlt_events_struct - * \param this a properties list - * \param pair a condition pair - */ - -static void mlt_events_listen_for( mlt_properties this, condition_pair *pair ) -{ - pthread_mutex_lock( &pair->mutex ); - if ( pair->done == 0 ) - { - pthread_cond_signal( &pair->cond ); - pthread_mutex_unlock( &pair->mutex ); - } -} - -/** Prepare to wait for an event. - * - * \public \memberof mlt_events_struct - * \param this a properties list - * \param id the name of the event to wait for - * \return an event - */ - -mlt_event mlt_events_setup_wait_for( mlt_properties this, const char *id ) -{ - condition_pair *pair = malloc( sizeof( condition_pair ) ); - pair->done = 0; - pthread_cond_init( &pair->cond, NULL ); - pthread_mutex_init( &pair->mutex, NULL ); - pthread_mutex_lock( &pair->mutex ); - return mlt_events_listen( this, pair, id, ( mlt_listener )mlt_events_listen_for ); -} - -/** Wait for an event. - * - * \public \memberof mlt_events_struct - * \param this a properties list - * \param event an event - */ - -void mlt_events_wait_for( mlt_properties this, mlt_event event ) -{ - if ( event != NULL ) - { - condition_pair *pair = event->service; - pthread_cond_wait( &pair->cond, &pair->mutex ); - } -} - -/** Cleanup after waiting for an event. - * - * \public \memberof mlt_events_struct - * \param this a properties list - * \param event an event - */ - -void mlt_events_close_wait_for( mlt_properties this, mlt_event event ) -{ - if ( event != NULL ) - { - condition_pair *pair = event->service; - event->owner = NULL; - pair->done = 0; - pthread_mutex_unlock( &pair->mutex ); - pthread_mutex_destroy( &pair->mutex ); - pthread_cond_destroy( &pair->cond ); - } -} - -/** Fetch the events object. - * - * \private \memberof mlt_events_struct - * \param this a properties list - * \return an events object - */ - -static mlt_events mlt_events_fetch( mlt_properties this ) -{ - mlt_events events = NULL; - if ( this != NULL ) - events = mlt_properties_get_data( this, "_events", NULL ); - return events; -} - -/** Store the events object. - * - * \private \memberof mlt_events_struct - * \param this a properties list - * \param events an events object - */ - -static void mlt_events_store( mlt_properties this, mlt_events events ) -{ - if ( this != NULL && events != NULL ) - mlt_properties_set_data( this, "_events", events, 0, ( mlt_destructor )mlt_events_close, NULL ); -} - -/** Close the events object. - * - * \private \memberof mlt_events_struct - * \param events an events object - */ - -static void mlt_events_close( mlt_events events ) -{ - if ( events != NULL ) - { - mlt_properties_close( events->list ); - free( events ); - } -}