diff --git a/libtransmission/internal.h b/libtransmission/internal.h index 641838e91..7fa506026 100644 --- a/libtransmission/internal.h +++ b/libtransmission/internal.h @@ -157,7 +157,8 @@ struct tr_torrent uint64_t stopDate; uint64_t activityDate; - uint8_t hasChangedState; + tr_torrent_status_func * status_func; + void * status_func_user_data; unsigned int runStatusToSaveIsSet : 1; unsigned int pexDisabled : 1; diff --git a/libtransmission/torrent.c b/libtransmission/torrent.c index 913289188..b0c9b0b15 100644 --- a/libtransmission/torrent.c +++ b/libtransmission/torrent.c @@ -304,7 +304,6 @@ torrentRealInit( tr_handle * h, tor->destination = tr_strdup( destination ); tor->handle = h; - tor->hasChangedState = -1; tor->pexDisabled = 0; tor->runStatusToSaveIsSet = FALSE; @@ -692,31 +691,6 @@ tr_torrentDisablePex( tr_torrent * tor, int disable ) tor->pexDisabled = disable; } -static int tr_didStateChangeTo ( tr_torrent * tor, int status ) -{ - int ret; - - tr_torrentLock( tor ); - if (( ret = tor->hasChangedState == status )) - tor->hasChangedState = -1; - tr_torrentUnlock( tor ); - - return ret; -} - -int tr_getIncomplete( tr_torrent * tor ) -{ - return tr_didStateChangeTo( tor, TR_CP_INCOMPLETE ); -} -int tr_getDone( tr_torrent * tor ) -{ - return tr_didStateChangeTo( tor, TR_CP_DONE ); -} -int tr_getComplete( tr_torrent * tor ) -{ - return tr_didStateChangeTo( tor, TR_CP_COMPLETE ); -} - void tr_manualUpdate( tr_torrent * tor ) { @@ -1117,6 +1091,36 @@ tr_torrentClose( tr_torrent * tor ) tr_timerNew( tor->handle, freeWhenStopped, tor, 250 ); } +/** +*** Completeness +**/ + +static void +fireStatusChange( tr_torrent * tor, cp_status_t status ) +{ + assert( tor != NULL ); + assert( status==TR_CP_INCOMPLETE || status==TR_CP_DONE || status==TR_CP_COMPLETE ); + + if( tor->status_func != NULL ) + (tor->status_func)( tor, status, tor->status_func_user_data ); +} + +void +tr_torrentSetStatusCallback( tr_torrent * tor, + tr_torrent_status_func func, + void * user_data ) +{ + assert( tor != NULL ); + tor->status_func = func; + tor->status_func_user_data = user_data; +} + +void +tr_torrentClearStatusCallback( tr_torrent * torrent ) +{ + tr_torrentSetStatusCallback( torrent, NULL, NULL ); +} + void tr_torrentRecheckCompleteness( tr_torrent * tor ) { @@ -1127,7 +1131,7 @@ tr_torrentRecheckCompleteness( tr_torrent * tor ) cpStatus = tr_cpGetStatus( tor->completion ); if( cpStatus != tor->cpStatus ) { tor->cpStatus = cpStatus; - tor->hasChangedState = tor->cpStatus; /* tell the client... */ + fireStatusChange( tor, cpStatus ); if( (cpStatus == TR_CP_COMPLETE) /* ...and if we're complete */ && tor->downloadedCur ) { /* and it just happened */ tr_trackerCompleted( tor->tracker ); /* tell the tracker */ diff --git a/libtransmission/transmission.h b/libtransmission/transmission.h index 589c218aa..a9d8faffa 100644 --- a/libtransmission/transmission.h +++ b/libtransmission/transmission.h @@ -443,16 +443,28 @@ void tr_torrentStart( tr_torrent * ); **********************************************************************/ void tr_torrentStop( tr_torrent * ); -/*********************************************************************** - * tr_getComplete, tr_getIncomplete and tr_getPartial - *********************************************************************** - * The first call after a torrent changed state returns 1. Returns 0 - * in other cases. - **********************************************************************/ -int tr_getIncomplete( tr_torrent * tor ); -int tr_getDone( tr_torrent * tor ); -int tr_getComplete( tr_torrent * tor ); +/** +*** Register to be notified whenever a torrent's state changes. +**/ + +typedef enum +{ + TR_CP_INCOMPLETE, /* doesn't have all the desired pieces */ + TR_CP_DONE, /* has all the pieces but the DND ones */ + TR_CP_COMPLETE /* has every piece */ +} +cp_status_t; + +typedef void (tr_torrent_status_func)(tr_torrent * torrent, + cp_status_t status, + void * user_data ); + +void tr_torrentSetStatusCallback( tr_torrent * torrent, + tr_torrent_status_func func, + void * user_data ); + +void tr_torrentClearStatusCallback( tr_torrent * torrent ); /** * MANUAL ANNOUNCE @@ -611,14 +623,6 @@ torrent_status_t; #define TR_STATUS_INACTIVE \ (TR_STATUS_STOPPING|TR_STATUS_STOPPED) -typedef enum -{ - TR_CP_INCOMPLETE, /* doesn't have all the desired pieces */ - TR_CP_DONE, /* has all the pieces but the DND ones */ - TR_CP_COMPLETE /* has every piece */ -} -cp_status_t; - /*********************************************************************** * tr_stat **********************************************************************/