mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-12 09:17:52 -06:00
Comments and refactoring
This commit is contained in:
parent
df625a0c4b
commit
d2c6190cc5
5 changed files with 170 additions and 14 deletions
|
@ -66,7 +66,7 @@ sub new {
|
||||||
$self->SetStatusBar($self->{statusbar});
|
$self->SetStatusBar($self->{statusbar});
|
||||||
|
|
||||||
# Make the global status bar and its progress indicator available in C++
|
# Make the global status bar and its progress indicator available in C++
|
||||||
$appController->set_global_progress_indicator_id(
|
$appController->set_global_progress_indicator(
|
||||||
$self->{statusbar}->{prog}->GetId(),
|
$self->{statusbar}->{prog}->GetId(),
|
||||||
$self->{statusbar}->GetId(),
|
$self->{statusbar}->GetId(),
|
||||||
);
|
);
|
||||||
|
|
|
@ -15,13 +15,27 @@ class Model;
|
||||||
class Print;
|
class Print;
|
||||||
class PrintObject;
|
class PrintObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A boilerplate class for creating application logic. It should provide
|
||||||
|
* features as issue reporting, gauge and progress indication, etc...
|
||||||
|
*
|
||||||
|
* The lower lever UI independent classes should be manipulated with a subclass
|
||||||
|
* of this controller class. We can also catch any exceptions that lower level
|
||||||
|
* methods could throw and display appropriate errors and warnings.
|
||||||
|
*
|
||||||
|
* Note that even the inner interface of this class free from any UI toolkit.
|
||||||
|
* We can implement it with any UI framework or make it a cli client.
|
||||||
|
*/
|
||||||
class AppControllerBoilerplate {
|
class AppControllerBoilerplate {
|
||||||
class PriMap;
|
class PriMap; // Some structure to store progress indication data
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/// A Progress indicator object smart pointer
|
||||||
using ProgresIndicatorPtr = std::shared_ptr<IProgressIndicator>;
|
using ProgresIndicatorPtr = std::shared_ptr<IProgressIndicator>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
// Pimpl data for thread safe progress indication features
|
||||||
std::unique_ptr<PriMap> progressind_;
|
std::unique_ptr<PriMap> progressind_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -32,6 +46,7 @@ public:
|
||||||
using Path = std::string;
|
using Path = std::string;
|
||||||
using PathList = std::vector<Path>;
|
using PathList = std::vector<Path>;
|
||||||
|
|
||||||
|
/// Common runtime issue types
|
||||||
enum class IssueType {
|
enum class IssueType {
|
||||||
INFO,
|
INFO,
|
||||||
WARN,
|
WARN,
|
||||||
|
@ -39,43 +54,102 @@ public:
|
||||||
FATAL
|
FATAL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Query some paths from the user.
|
||||||
|
*
|
||||||
|
* It should display a file chooser dialog in case of a UI application.
|
||||||
|
* @param title Title of a possible query dialog.
|
||||||
|
* @param extensions Recognized file extensions.
|
||||||
|
* @return Returns a list of paths choosed by the user.
|
||||||
|
*/
|
||||||
PathList query_destination_paths(
|
PathList query_destination_paths(
|
||||||
const std::string& title,
|
const std::string& title,
|
||||||
const std::string& extensions) const;
|
const std::string& extensions) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Same as query_destination_paths but works for directories only.
|
||||||
|
*/
|
||||||
PathList query_destination_dirs(
|
PathList query_destination_dirs(
|
||||||
const std::string& title) const;
|
const std::string& title) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Same as query_destination_path but returns only one path.
|
||||||
|
*/
|
||||||
Path query_destination_path(
|
Path query_destination_path(
|
||||||
const std::string& title,
|
const std::string& title,
|
||||||
const std::string& extensions,
|
const std::string& extensions,
|
||||||
const std::string& hint = "") const;
|
const std::string& hint = "") const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Report an issue to the user be it fatal or recoverable.
|
||||||
|
*
|
||||||
|
* In a UI app this should display some message dialog.
|
||||||
|
*
|
||||||
|
* @param issuetype The type of the runtime issue.
|
||||||
|
* @param description A somewhat longer description of the issue.
|
||||||
|
* @param brief A very brief description. Can be used for message dialog
|
||||||
|
* title.
|
||||||
|
*/
|
||||||
void report_issue(IssueType issuetype,
|
void report_issue(IssueType issuetype,
|
||||||
const std::string& description,
|
const std::string& description,
|
||||||
const std::string& brief = "");
|
const std::string& brief = "");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set up a progress indicator for the current thread.
|
||||||
|
* @param progrind An already created progress indicator object.
|
||||||
|
*/
|
||||||
void progress_indicator(ProgresIndicatorPtr progrind);
|
void progress_indicator(ProgresIndicatorPtr progrind);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create and set up a new progress indicator for the current thread.
|
||||||
|
* @param statenum The number of states for the given procedure.
|
||||||
|
* @param title The title of the procedure.
|
||||||
|
* @param firstmsg The message for the first subtask to be displayed.
|
||||||
|
*/
|
||||||
void progress_indicator(unsigned statenum,
|
void progress_indicator(unsigned statenum,
|
||||||
const std::string& title,
|
const std::string& title,
|
||||||
const std::string& firstmsg = "");
|
const std::string& firstmsg = "");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return the progress indicator set up for the current thread. This
|
||||||
|
* can be empty as well.
|
||||||
|
* @return A progress indicator object implementing IProgressIndicator. If
|
||||||
|
* a global progress indicator is available for the current implementation
|
||||||
|
* than this will be set up for the current thread and returned.
|
||||||
|
*/
|
||||||
ProgresIndicatorPtr progress_indicator();
|
ProgresIndicatorPtr progress_indicator();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A predicate telling the caller whether it is the thread that
|
||||||
|
* created the AppConroller object itself. This probably means that the
|
||||||
|
* execution is in the UI thread. Otherwise it returns false meaning that
|
||||||
|
* some worker thread called this function.
|
||||||
|
* @return Return true if for the same caller thread that created this
|
||||||
|
* object and false for every other.
|
||||||
|
*/
|
||||||
bool is_main_thread() const;
|
bool is_main_thread() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create a new progress indicator and retirn a smart pointer to it.
|
||||||
|
* @param statenum The number of states for the given procedure.
|
||||||
|
* @param title The title of the procedure.
|
||||||
|
* @param firstmsg The message for the first subtask to be displayed.
|
||||||
|
* @return Smart pointer to the created object.
|
||||||
|
*/
|
||||||
ProgresIndicatorPtr create_progress_indicator(
|
ProgresIndicatorPtr create_progress_indicator(
|
||||||
unsigned statenum,
|
unsigned statenum,
|
||||||
const std::string& title,
|
const std::string& title,
|
||||||
const std::string& firstmsg = "") const;
|
const std::string& firstmsg = "") const;
|
||||||
|
|
||||||
|
// This is a global
|
||||||
ProgresIndicatorPtr global_progressind_;
|
ProgresIndicatorPtr global_progressind_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Implementation of the printing logic.
|
||||||
|
*/
|
||||||
class PrintController: public AppControllerBoilerplate {
|
class PrintController: public AppControllerBoilerplate {
|
||||||
Print *print_ = nullptr;
|
Print *print_ = nullptr;
|
||||||
protected:
|
protected:
|
||||||
|
@ -102,35 +176,85 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
using Ptr = std::unique_ptr<PrintController>;
|
// Must be public for perl to use it
|
||||||
|
|
||||||
explicit inline PrintController(Print *print): print_(print) {}
|
explicit inline PrintController(Print *print): print_(print) {}
|
||||||
|
|
||||||
|
PrintController(const PrintController&) = delete;
|
||||||
|
PrintController(PrintController&&) = delete;
|
||||||
|
|
||||||
|
using Ptr = std::unique_ptr<PrintController>;
|
||||||
|
|
||||||
inline static Ptr create(Print *print) {
|
inline static Ptr create(Print *print) {
|
||||||
return PrintController::Ptr( new PrintController(print) );
|
return PrintController::Ptr( new PrintController(print) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Slice one pront object.
|
||||||
|
* @param pobj The print object.
|
||||||
|
*/
|
||||||
void slice(PrintObject *pobj);
|
void slice(PrintObject *pobj);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Slice the loaded print scene.
|
||||||
|
*/
|
||||||
void slice();
|
void slice();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Slice the print into zipped png files.
|
||||||
|
*/
|
||||||
void slice_to_png();
|
void slice_to_png();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Top level controller.
|
||||||
|
*/
|
||||||
class AppController: public AppControllerBoilerplate {
|
class AppController: public AppControllerBoilerplate {
|
||||||
Model *model_ = nullptr;
|
Model *model_ = nullptr;
|
||||||
PrintController::Ptr printctl;
|
PrintController::Ptr printctl;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the print controller object.
|
||||||
|
*
|
||||||
|
* @return Return a raw pointer instead of a smart one for perl to be able
|
||||||
|
* to use this function and access the print controller.
|
||||||
|
*/
|
||||||
PrintController * print_ctl() { return printctl.get(); }
|
PrintController * print_ctl() { return printctl.get(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set a model object.
|
||||||
|
*
|
||||||
|
* @param model A raw pointer to the model object. This can be used from
|
||||||
|
* perl.
|
||||||
|
*/
|
||||||
void set_model(Model *model) { model_ = model; }
|
void set_model(Model *model) { model_ = model; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the print object from perl.
|
||||||
|
*
|
||||||
|
* This will create a print controller that will then be accessible from
|
||||||
|
* perl.
|
||||||
|
* @param print A print object which can be a perl-ish extension as well.
|
||||||
|
*/
|
||||||
void set_print(Print *print) {
|
void set_print(Print *print) {
|
||||||
printctl = PrintController::create(print);
|
printctl = PrintController::create(print);
|
||||||
printctl->progress_indicator(progress_indicator());
|
printctl->progress_indicator(progress_indicator());
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_global_progress_indicator_id(unsigned gauge_id,
|
/**
|
||||||
|
* @brief Set up a global progress indicator.
|
||||||
|
*
|
||||||
|
* In perl we have a progress indicating status bar on the bottom of the
|
||||||
|
* window which is defined and created in perl. We can pass the ID-s of the
|
||||||
|
* gauge and the statusbar id and make a wrapper implementation of the
|
||||||
|
* IProgressIndicator interface so we can use this GUI widget from C++.
|
||||||
|
*
|
||||||
|
* This function should be called from perl.
|
||||||
|
*
|
||||||
|
* @param gauge_id The ID of the gague widget of the status bar.
|
||||||
|
* @param statusbar_id The ID of the status bar.
|
||||||
|
*/
|
||||||
|
void set_global_progress_indicator(unsigned gauge_id,
|
||||||
unsigned statusbar_id);
|
unsigned statusbar_id);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -133,7 +133,7 @@ public:
|
||||||
if( val >= 1.0) state(static_cast<unsigned>(val));
|
if( val >= 1.0) state(static_cast<unsigned>(val));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void state(unsigned st) override {
|
void state(unsigned st) {
|
||||||
// send status update event
|
// send status update event
|
||||||
if(is_asynch_) {
|
if(is_asynch_) {
|
||||||
auto evt = new wxCommandEvent(PROGRESS_STATUS_UPDATE_EVENT, id_);
|
auto evt = new wxCommandEvent(PROGRESS_STATUS_UPDATE_EVENT, id_);
|
||||||
|
@ -225,7 +225,7 @@ public:
|
||||||
if(val >= 1.0) state(unsigned(val));
|
if(val >= 1.0) state(unsigned(val));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void state(unsigned st) override {
|
void state(unsigned st) {
|
||||||
if(!ctl_.is_main_thread()) {
|
if(!ctl_.is_main_thread()) {
|
||||||
auto evt = new wxCommandEvent(PROGRESS_STATUS_UPDATE_EVENT, id_);
|
auto evt = new wxCommandEvent(PROGRESS_STATUS_UPDATE_EVENT, id_);
|
||||||
evt->SetInt(st);
|
evt->SetInt(st);
|
||||||
|
@ -249,7 +249,7 @@ public:
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppController::set_global_progress_indicator_id(
|
void AppController::set_global_progress_indicator(
|
||||||
unsigned gid,
|
unsigned gid,
|
||||||
unsigned sid)
|
unsigned sid)
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,40 +6,72 @@
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Generic progress indication interface.
|
||||||
|
*/
|
||||||
class IProgressIndicator {
|
class IProgressIndicator {
|
||||||
public:
|
public:
|
||||||
using CancelFn = std::function<void(void)>;
|
using CancelFn = std::function<void(void)>; // Cancel functio signature.
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float state_ = .0f, max_ = 1.f, step_;
|
float state_ = .0f, max_ = 1.f, step_;
|
||||||
std::function<void(void)> cancelfunc_ = [](){};
|
std::function<void(void)> cancelfunc_ = [](){};
|
||||||
unsigned proc_count_ = 1;
|
unsigned proc_count_ = 1;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
inline virtual ~IProgressIndicator() {}
|
inline virtual ~IProgressIndicator() {}
|
||||||
|
|
||||||
|
/// Get the maximum of the progress range.
|
||||||
float max() const { return max_; }
|
float max() const { return max_; }
|
||||||
|
|
||||||
|
/// Get the current progress state
|
||||||
float state() const { return state_; }
|
float state() const { return state_; }
|
||||||
|
|
||||||
|
/// Set the maximum of hte progress range
|
||||||
virtual void max(float maxval) { max_ = maxval; }
|
virtual void max(float maxval) { max_ = maxval; }
|
||||||
|
|
||||||
|
/// Set the current state of the progress.
|
||||||
virtual void state(float val) { state_ = val; }
|
virtual void state(float val) { state_ = val; }
|
||||||
virtual void state(unsigned st) { state_ = st * step_; }
|
|
||||||
|
/**
|
||||||
|
* @brief Number of states int the progress. Can be used insted of giving a
|
||||||
|
* maximum value.
|
||||||
|
*/
|
||||||
virtual void states(unsigned statenum) {
|
virtual void states(unsigned statenum) {
|
||||||
step_ = max_ / statenum;
|
step_ = max_ / statenum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Message shown on the next status update.
|
||||||
virtual void message(const std::string&) = 0;
|
virtual void message(const std::string&) = 0;
|
||||||
|
|
||||||
|
/// Title of the operaton.
|
||||||
virtual void title(const std::string&) = 0;
|
virtual void title(const std::string&) = 0;
|
||||||
|
|
||||||
|
/// Formatted message for the next status update. Works just like sprinf.
|
||||||
virtual void message_fmt(const std::string& fmt, ...);
|
virtual void message_fmt(const std::string& fmt, ...);
|
||||||
|
|
||||||
|
/// Set up a cancel callback for the operation if feasible.
|
||||||
inline void on_cancel(CancelFn func) { cancelfunc_ = func; }
|
inline void on_cancel(CancelFn func) { cancelfunc_ = func; }
|
||||||
|
|
||||||
|
/// Call a previously specified cancel callback.
|
||||||
inline void on_cancel() { cancelfunc_(); }
|
inline void on_cancel() { cancelfunc_(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Set up how many subprocedures does the whole operation contain.
|
||||||
|
*
|
||||||
|
* This was neccesary from practical reasons. If the progress indicator is
|
||||||
|
* a dialog and we want to show the progress of a few sub operations than
|
||||||
|
* the dialog wont be closed and reopened each time a new sub operation is
|
||||||
|
* started. This is not a mandatory feature and can be ignored completely.
|
||||||
|
*/
|
||||||
inline void procedure_count(unsigned pc) { proc_count_ = pc; }
|
inline void procedure_count(unsigned pc) { proc_count_ = pc; }
|
||||||
|
|
||||||
|
/// Get the current procedure count
|
||||||
inline unsigned procedure_count() const { return proc_count_; }
|
inline unsigned procedure_count() const { return proc_count_; }
|
||||||
|
|
||||||
template<class T> void update(T st, const std::string& msg) {
|
/// Convinience function to call message and status update in one function.
|
||||||
|
void update(float st, const std::string& msg) {
|
||||||
message(msg); state(st);
|
message(msg); state(st);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -22,5 +22,5 @@
|
||||||
PrintController *print_ctl();
|
PrintController *print_ctl();
|
||||||
void set_model(Model *model);
|
void set_model(Model *model);
|
||||||
void set_print(Print *print);
|
void set_print(Print *print);
|
||||||
void set_global_progress_indicator_id(unsigned gauge_id, unsigned statusbar_id);
|
void set_global_progress_indicator(unsigned gauge_id, unsigned statusbar_id);
|
||||||
};
|
};
|
Loading…
Add table
Add a link
Reference in a new issue