|
1
|
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 };
|