Mercurial > foo_out_sdl
comparison foosdk/sdk/foobar2000/SDK/threaded_process.h @ 1:20d02a178406 default tip
*: check in everything else
yay
| author | Paper <paper@tflc.us> |
|---|---|
| date | Mon, 05 Jan 2026 02:15:46 -0500 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 0:e9bb126753e7 | 1:20d02a178406 |
|---|---|
| 1 #pragma once | |
| 2 #include <functional> | |
| 3 | |
| 4 //! Callback class passed to your threaded_process client code; allows you to give various visual feedback to the user. | |
| 5 class threaded_process_status { | |
| 6 public: | |
| 7 enum {progress_min = 0, progress_max = 5000}; | |
| 8 | |
| 9 //! Sets the primary progress bar state; scale from progress_min to progress_max. | |
| 10 virtual void set_progress(t_size p_state) { (void)p_state; } | |
| 11 //! Sets the secondary progress bar state; scale from progress_min to progress_max. | |
| 12 virtual void set_progress_secondary(t_size p_state) { (void)p_state; } | |
| 13 //! Sets the currently progressed item label. When working with files, you should use set_file_path() instead. | |
| 14 virtual void set_item(const char* p_item, t_size p_item_len = SIZE_MAX) { (void)p_item; (void)p_item_len; } | |
| 15 //! Sets the currently progressed item label; treats the label as a file path. | |
| 16 virtual void set_item_path(const char* p_item, t_size p_item_len = SIZE_MAX) { (void)p_item; (void)p_item_len; } | |
| 17 //! Sets the title of the dialog. You normally don't need this function unless you want to override the title you set when initializing the threaded_process. | |
| 18 virtual void set_title(const char* p_title, t_size p_title_len = SIZE_MAX) { (void)p_title; (void)p_title_len; } | |
| 19 //! Should not be used. | |
| 20 virtual void force_update() {} | |
| 21 //! Returns whether the process is paused. | |
| 22 virtual bool is_paused() {return false;} | |
| 23 | |
| 24 //! Checks if process is paused and sleeps if needed; returns false when process should be aborted, true on success. \n | |
| 25 //! You should use poll_pause() instead of calling this directly. | |
| 26 virtual bool process_pause() {return true;} | |
| 27 | |
| 28 //! Automatically sleeps if the process is paused. | |
| 29 void poll_pause() {if (!process_pause()) throw exception_aborted();} | |
| 30 | |
| 31 //! Helper; sets primary progress with a custom scale. | |
| 32 void set_progress(t_size p_state,t_size p_max); | |
| 33 //! Helper; sets secondary progress with a custom scale. | |
| 34 void set_progress_secondary(t_size p_state,t_size p_max); | |
| 35 //! Helper; sets primary progress with a float 0..1 scale. | |
| 36 void set_progress_float(double p_state); | |
| 37 //! Helper; sets secondary progress with a float 0..1 scale. | |
| 38 void set_progress_secondary_float(double p_state); | |
| 39 //! Helper; gracefully reports multiple items being concurrently worked on. | |
| 40 void set_items( metadb_handle_list_cref items ); | |
| 41 void set_items( pfc::list_base_const_t<const char*> const & paths ); | |
| 42 }; | |
| 43 | |
| 44 //! Fb2k mobile compatibility | |
| 45 class threaded_process_context { | |
| 46 public: | |
| 47 static fb2k::hwnd_t g_default() { return core_api::get_main_window(); } | |
| 48 }; | |
| 49 | |
| 50 //! Callback class for the threaded_process API. You must implement this to create your own threaded_process client. | |
| 51 class NOVTABLE threaded_process_callback : public service_base { | |
| 52 public: | |
| 53 typedef fb2k::hwnd_t ctx_t; | |
| 54 | |
| 55 //! Called from the main thread before spawning the worker thread. \n | |
| 56 //! Note that you should not access the window handle passed to on_init() in the worker thread later on. | |
| 57 virtual void on_init(ctx_t p_wnd) { (void)p_wnd; } | |
| 58 //! Called from the worker thread. Do all the hard work here. | |
| 59 virtual void run(threaded_process_status & p_status,abort_callback & p_abort) = 0; | |
| 60 //! Called after the worker thread has finished executing. | |
| 61 virtual void on_done(ctx_t p_wnd, bool p_was_aborted) { (void)p_wnd; (void)p_was_aborted; } | |
| 62 | |
| 63 //! Safely prevent destruction from worker threads. | |
| 64 static bool serviceRequiresMainThreadDestructor() { return true; } | |
| 65 | |
| 66 FB2K_MAKE_SERVICE_INTERFACE(threaded_process_callback,service_base); | |
| 67 }; | |
| 68 | |
| 69 | |
| 70 //! The threaded_process API allows you to easily put timeconsuming tasks in worker threads, with progress dialog giving nice feedback to the user. \n | |
| 71 //! Thanks to this API you can perform such tasks with no user interface related programming at all. | |
| 72 class NOVTABLE threaded_process : public service_base { | |
| 73 public: | |
| 74 enum { | |
| 75 //! Shows the "abort" button. | |
| 76 flag_show_abort = 1, | |
| 77 //! Obsolete, do not use. | |
| 78 flag_show_minimize = 1 << 1, | |
| 79 //! Shows a progress bar. | |
| 80 flag_show_progress = 1 << 2, | |
| 81 //! Shows dual progress bars; implies flag_show_progress. | |
| 82 flag_show_progress_dual = 1 << 3, | |
| 83 //! Shows the item being currently processed. | |
| 84 flag_show_item = 1 << 4, | |
| 85 //! Shows the "pause" button. | |
| 86 flag_show_pause = 1 << 5, | |
| 87 //! Obsolete, do not use. | |
| 88 flag_high_priority = 1 << 6, | |
| 89 //! Make the dialog hidden by default and show it only if the operation could not be completed after 500ms. Implies flag_no_focus. Relevant only to modeless dialogs. | |
| 90 flag_show_delayed = 1 << 7, | |
| 91 //! Do not focus the dialog by default. | |
| 92 flag_no_focus = 1 << 8, | |
| 93 //! \since 2.0 | |
| 94 //! Do not show any user interface, just run the operation quietly. | |
| 95 flag_silent = 1 << 9, | |
| 96 }; | |
| 97 | |
| 98 //! Runs a synchronous threaded_process operation - the function does not return until the operation has completed, though the app UI is not frozen and the operation is abortable. \n | |
| 99 //! This API is obsolete and should not be used. Please use run_modeless() instead if possible. \n | |
| 100 //! Call from main thread only. | |
| 101 //! @param p_callback Interface to your threaded_process client. | |
| 102 //! @param p_flags Flags describing requested dialog functionality. See threaded_process::flag_* constants. | |
| 103 //! @param p_parent Parent window for the progress dialog - typically core_api::get_main_window(). | |
| 104 //! @param p_title Initial title of the dialog. | |
| 105 //! @returns True if the operation has completed normally, false if the user has aborted the operation. In case of a catastrophic failure such as dialog creation failure, exceptions will be thrown. | |
| 106 virtual bool run_modal(service_ptr_t<threaded_process_callback> p_callback,unsigned p_flags,fb2k::hwnd_t p_parent,const char * p_title,t_size p_title_len = SIZE_MAX) = 0; | |
| 107 //! Runs an asynchronous threaded_process operation. \n | |
| 108 //! Call from main thread only. | |
| 109 //! @param p_callback Interface to your threaded_process client. | |
| 110 //! @param p_flags Flags describing requested dialog functionality. See threaded_process::flag_* constants. | |
| 111 //! @param p_parent Parent window for the progress dialog - typically core_api::get_main_window(). | |
| 112 //! @param p_title Initial title of the dialog. | |
| 113 //! @returns True, always; the return value should be ignored. In case of a catastrophic failure such as dialog creation failure, exceptions will be thrown. | |
| 114 virtual bool run_modeless(service_ptr_t<threaded_process_callback> p_callback,unsigned p_flags,fb2k::hwnd_t p_parent,const char * p_title,t_size p_title_len = SIZE_MAX) = 0; | |
| 115 | |
| 116 | |
| 117 //! Helper invoking run_modal(). | |
| 118 static bool g_run_modal(service_ptr_t<threaded_process_callback> p_callback,unsigned p_flags,fb2k::hwnd_t p_parent,const char * p_title,t_size p_title_len = SIZE_MAX); | |
| 119 //! Helper invoking run_modeless(). | |
| 120 static bool g_run_modeless(service_ptr_t<threaded_process_callback> p_callback,unsigned p_flags,fb2k::hwnd_t p_parent,const char * p_title,t_size p_title_len = SIZE_MAX); | |
| 121 | |
| 122 //! Queries user settings; returns whether various timeconsuming tasks should be blocking machine standby. | |
| 123 static bool g_query_preventStandby(); | |
| 124 | |
| 125 FB2K_MAKE_SERVICE_COREAPI(threaded_process); | |
| 126 }; | |
| 127 | |
| 128 | |
| 129 //! Helper - forward threaded_process_callback calls to a service object that for whatever reason cannot publish threaded_process_callback API by itself. | |
| 130 template<typename TTarget> class threaded_process_callback_redir : public threaded_process_callback { | |
| 131 public: | |
| 132 threaded_process_callback_redir(TTarget * target) : m_target(target) {} | |
| 133 void on_init(ctx_t p_wnd) {m_target->tpc_on_init(p_wnd);} | |
| 134 void run(threaded_process_status & p_status,abort_callback & p_abort) {m_target->tpc_run(p_status, p_abort);} | |
| 135 void on_done(ctx_t p_wnd,bool p_was_aborted) {m_target->tpc_on_done(p_wnd, p_was_aborted); } | |
| 136 private: | |
| 137 const service_ptr_t<TTarget> m_target; | |
| 138 }; | |
| 139 | |
| 140 //! Helper - lambda based threaded_process_callback implementation | |
| 141 class threaded_process_callback_lambda : public threaded_process_callback { | |
| 142 public: | |
| 143 typedef std::function<void(ctx_t)> on_init_t; | |
| 144 typedef std::function<void(threaded_process_status&, abort_callback&)> run_t; | |
| 145 typedef std::function<void(ctx_t, bool)> on_done_t; | |
| 146 | |
| 147 static service_ptr_t<threaded_process_callback_lambda> create(); | |
| 148 static service_ptr_t<threaded_process_callback_lambda> create(run_t f); | |
| 149 static service_ptr_t<threaded_process_callback_lambda> create(on_init_t f1, run_t f2, on_done_t f3); | |
| 150 | |
| 151 on_init_t m_on_init; | |
| 152 run_t m_run; | |
| 153 on_done_t m_on_done; | |
| 154 | |
| 155 void on_init(ctx_t p_ctx); | |
| 156 void run(threaded_process_status & p_status, abort_callback & p_abort); | |
| 157 void on_done(ctx_t p_ctx, bool p_was_aborted); | |
| 158 }; |
