diff --git a/src/core/chuck_dl.cpp b/src/core/chuck_dl.cpp index 490311deb..8d9b19e6e 100644 --- a/src/core/chuck_dl.cpp +++ b/src/core/chuck_dl.cpp @@ -825,6 +825,16 @@ Chuck_DL_MainThreadHook * CK_DLL_CALL ck_create_main_thread_hook( Chuck_DL_Query return new Chuck_DL_MainThreadHook( hook, quit, bindle, query->carrier() ); } +//----------------------------------------------------------------------------- +// name: ck_register_callback_on_shutdown() | 1.5.2.5 (ge) added +// desc: register a callback function to be called on host exit +// (both natural or SIGINT) +//----------------------------------------------------------------------------- +void CK_DLL_CALL ck_register_callback_on_shutdown( Chuck_DL_Query * query, f_callback_on_shutdown cb, void * bindle ) +{ + // register + query->vm()->register_callback_on_shutdown( cb, bindle ); +} //----------------------------------------------------------------------------- // name: ck_register_shreds_watcher() @@ -1351,6 +1361,7 @@ Chuck_DL_Query::Chuck_DL_Query( Chuck_Carrier * carrier, Chuck_DLL * dll ) create_main_thread_hook = ck_create_main_thread_hook; register_shreds_watcher = ck_register_shreds_watcher; // 1.5.1.5 (ge & andrew) unregister_shreds_watcher = ck_unregister_shreds_watcher; // 1.5.1.5 (ge & andrew) + register_callback_on_shutdown = ck_register_callback_on_shutdown; // 1.5.2.5 (ge) m_carrier = carrier; dll_ref = dll; // 1.5.1.3 (ge) added diff --git a/src/core/chuck_dl.h b/src/core/chuck_dl.h index dc4507793..5a87dc041 100644 --- a/src/core/chuck_dl.h +++ b/src/core/chuck_dl.h @@ -340,6 +340,8 @@ typedef t_CKBOOL (CK_DLL_CALL * f_tock)( Chuck_Object * SELF, Chuck_UAna * UANA, typedef t_CKBOOL (CK_DLL_CALL * f_mainthreadhook)( void * bindle ); // "main thread" quit (stop running hook) typedef t_CKBOOL (CK_DLL_CALL * f_mainthreadquit)( void * bindle ); +// callback function, called on host shutdown +typedef void (CK_DLL_CALL * f_callback_on_shutdown)( void * bindle ); // shreds watcher callback typedef void (CK_DLL_CALL * f_shreds_watcher)( Chuck_VM_Shred * SHRED, t_CKINT CODE, t_CKINT PARAM, Chuck_VM * VM, void * BINDLE ); // type instantiation callback @@ -414,6 +416,8 @@ typedef void (CK_DLL_CALL * f_add_ugen_funcf_auto_num_channels)( Chuck_DL_Query typedef t_CKBOOL (CK_DLL_CALL * f_end_class)( Chuck_DL_Query * query ); // create main thread hook- used for executing a "hook" function in the main thread of a primary chuck instance typedef Chuck_DL_MainThreadHook * (CK_DLL_CALL * f_create_main_thread_hook)( Chuck_DL_Query * query, f_mainthreadhook hook, f_mainthreadquit quit, void * bindle ); +// register a callback to be called on host shutdown, e.g., for chugin cleanup +typedef void (CK_DLL_CALL * f_register_callback_on_shutdown)( Chuck_DL_Query * query, f_callback_on_shutdown cb, void * bindle ); // register a callback function to receive notification from the VM about shreds (add, remove, etc.) typedef void (CK_DLL_CALL * f_register_shreds_watcher)( Chuck_DL_Query * query, f_shreds_watcher cb, t_CKUINT options, void * bindle ); // unregister a shreds notification callback @@ -589,6 +593,14 @@ struct Chuck_DL_Query // ------------- f_create_main_thread_hook create_main_thread_hook; +public: + // ------------- + // register a function to be run on host shutdown; this can be used + // for chugin cleanup when the host (chuck, miniAudicle, etc.) exits + // including on SIGINT (ctrl-c termination) | added 1.5.2.5 (ge) + // ------------- + f_register_callback_on_shutdown register_callback_on_shutdown; + public: // ------------- // register callback to be invoked by chuck host at various diff --git a/src/core/chuck_vm.cpp b/src/core/chuck_vm.cpp index 673289417..957a6b2ac 100644 --- a/src/core/chuck_vm.cpp +++ b/src/core/chuck_vm.cpp @@ -471,6 +471,9 @@ t_CKBOOL Chuck_VM::shutdown() // set state m_init = FALSE; + // notify registered callbacks we are shutting down | 1.5.2.5 (ge) added + notify_callbacks_on_shutdown(); + // relockdown (added 1.3.6.0) // REFACTOR-2017: TODO -- remove once made per-VM Chuck_VM_Object::lock_all(); @@ -1431,6 +1434,52 @@ Chuck_VM_Shred * Chuck_VM::get_current_shred() const +//----------------------------------------------------------------------------- +// name: register_callback_on_shutdown() +// cesc: register a callback to be called on VM shutdown | 1.5.2.5 (ge) added +//----------------------------------------------------------------------------- +void Chuck_VM::register_callback_on_shutdown( f_callback_on_shutdown cb, void * bindle ) +{ + // check + if( !cb ) return; + + // ensure no duplicates + list::iterator it = std::find( m_callbacks_on_shutdown.begin(), + m_callbacks_on_shutdown.end(), cb ); + // add if not already preset + if( it == m_callbacks_on_shutdown.end() ) + { + // append + m_callbacks_on_shutdown.push_back( Chuck_VM_Callback_On_Shutdown(cb, bindle) ); + } +} + + + + +//----------------------------------------------------------------------------- +// name: notify_callbacks_on_shutdown() +// desc: notify callbacks on VM shutdown | 1.5.2.5 (ge) added +//----------------------------------------------------------------------------- +void Chuck_VM::notify_callbacks_on_shutdown() +{ + // the function to call eventually + f_callback_on_shutdown f = NULL; + // iterator + list::iterator it; + // iterate + for( it = m_callbacks_on_shutdown.begin(); it != m_callbacks_on_shutdown.end(); it++ ) + { + // the function + f = (*it).cb; + // call it with user data + f( (*it).userdata ); + } +} + + + + //----------------------------------------------------------------------------- // name: notify_watchers() // desc: notify watchers for a particular subscription | 1.5.1.5 diff --git a/src/core/chuck_vm.h b/src/core/chuck_vm.h index 855d514b3..16ac45b56 100644 --- a/src/core/chuck_vm.h +++ b/src/core/chuck_vm.h @@ -412,6 +412,33 @@ struct Chuck_VM_Status : public Chuck_Object +//----------------------------------------------------------------------------- +// name: struct Chuck_VM_Callback_On_Shutdown +// desc: an entry for a callback to be called on VM shutdown +//----------------------------------------------------------------------------- +struct Chuck_VM_Callback_On_Shutdown +{ + // function pointer to call + f_callback_on_shutdown cb; + // user data + void * userdata; + + // constructor + Chuck_VM_Callback_On_Shutdown( f_callback_on_shutdown f = NULL, void * data = NULL ) + : cb(f), userdata(data) { } + + // copy constructor + Chuck_VM_Callback_On_Shutdown( const Chuck_VM_Callback_On_Shutdown & other ) + : cb(other.cb), userdata(other.userdata) { } + + // == + bool operator ==( const Chuck_VM_Callback_On_Shutdown & other ) + { return this->cb == other.cb; } +}; + + + + //----------------------------------------------------------------------------- // name: struct Chuck_VM_Shreduler // desc: a ChucK shreduler shredules shreds @@ -657,6 +684,14 @@ struct Chuck_VM : public Chuck_Object // remove shreds watcher callback | 1.5.1.5 void remove_watcher( f_shreds_watcher cb ); +public: + // register a callback to be called on VM shutdown | 1.5.2.5 (ge) added + void register_callback_on_shutdown( f_callback_on_shutdown cb, void * bindle ); + +protected: + // notify callbacks on VM shutdown | 1.5.2.5 (ge) added + void notify_callbacks_on_shutdown(); + //----------------------------------------------------------------------------- // data //----------------------------------------------------------------------------- @@ -733,6 +768,10 @@ struct Chuck_VM : public Chuck_Object std::list m_shreds_watchers_remove; std::list m_shreds_watchers_suspend; std::list m_shreds_watchers_activate; + +protected: + // 1.5.2.5 (ge) on major VM events callbacks + std::list m_callbacks_on_shutdown; };