Comments and refactoring

This commit is contained in:
tamasmeszaros 2018-06-26 17:02:46 +02:00
parent df625a0c4b
commit d2c6190cc5
5 changed files with 170 additions and 14 deletions

View file

@ -66,7 +66,7 @@ sub new {
$self->SetStatusBar($self->{statusbar});
# 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}->GetId(),
);

View file

@ -15,13 +15,27 @@ class Model;
class Print;
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 PriMap;
class PriMap; // Some structure to store progress indication data
public:
/// A Progress indicator object smart pointer
using ProgresIndicatorPtr = std::shared_ptr<IProgressIndicator>;
private:
// Pimpl data for thread safe progress indication features
std::unique_ptr<PriMap> progressind_;
public:
@ -32,6 +46,7 @@ public:
using Path = std::string;
using PathList = std::vector<Path>;
/// Common runtime issue types
enum class IssueType {
INFO,
WARN,
@ -39,43 +54,102 @@ public:
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(
const std::string& title,
const std::string& extensions) const;
/**
* @brief Same as query_destination_paths but works for directories only.
*/
PathList query_destination_dirs(
const std::string& title) const;
/**
* @brief Same as query_destination_path but returns only one path.
*/
Path query_destination_path(
const std::string& title,
const std::string& extensions,
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,
const std::string& description,
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);
/**
* @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,
const std::string& title,
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();
/**
* @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;
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(
unsigned statenum,
const std::string& title,
const std::string& firstmsg = "") const;
// This is a global
ProgresIndicatorPtr global_progressind_;
};
/**
* @brief Implementation of the printing logic.
*/
class PrintController: public AppControllerBoilerplate {
Print *print_ = nullptr;
protected:
@ -102,35 +176,85 @@ protected:
public:
using Ptr = std::unique_ptr<PrintController>;
// Must be public for perl to use it
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) {
return PrintController::Ptr( new PrintController(print) );
}
/**
* @brief Slice one pront object.
* @param pobj The print object.
*/
void slice(PrintObject *pobj);
/**
* @brief Slice the loaded print scene.
*/
void slice();
/**
* @brief Slice the print into zipped png files.
*/
void slice_to_png();
};
/**
* @brief Top level controller.
*/
class AppController: public AppControllerBoilerplate {
Model *model_ = nullptr;
PrintController::Ptr printctl;
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(); }
/**
* @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; }
/**
* @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) {
printctl = PrintController::create(print);
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);
};

View file

@ -133,7 +133,7 @@ public:
if( val >= 1.0) state(static_cast<unsigned>(val));
}
virtual void state(unsigned st) override {
void state(unsigned st) {
// send status update event
if(is_asynch_) {
auto evt = new wxCommandEvent(PROGRESS_STATUS_UPDATE_EVENT, id_);
@ -225,7 +225,7 @@ public:
if(val >= 1.0) state(unsigned(val));
}
virtual void state(unsigned st) override {
void state(unsigned st) {
if(!ctl_.is_main_thread()) {
auto evt = new wxCommandEvent(PROGRESS_STATUS_UPDATE_EVENT, id_);
evt->SetInt(st);
@ -249,7 +249,7 @@ public:
};
}
void AppController::set_global_progress_indicator_id(
void AppController::set_global_progress_indicator(
unsigned gid,
unsigned sid)
{

View file

@ -6,40 +6,72 @@
namespace Slic3r {
/**
* @brief Generic progress indication interface.
*/
class IProgressIndicator {
public:
using CancelFn = std::function<void(void)>;
using CancelFn = std::function<void(void)>; // Cancel functio signature.
private:
float state_ = .0f, max_ = 1.f, step_;
std::function<void(void)> cancelfunc_ = [](){};
unsigned proc_count_ = 1;
public:
inline virtual ~IProgressIndicator() {}
/// Get the maximum of the progress range.
float max() const { return max_; }
/// Get the current progress state
float state() const { return state_; }
/// Set the maximum of hte progress range
virtual void max(float maxval) { max_ = maxval; }
/// Set the current state of the progress.
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) {
step_ = max_ / statenum;
}
/// Message shown on the next status update.
virtual void message(const std::string&) = 0;
/// Title of the operaton.
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, ...);
/// Set up a cancel callback for the operation if feasible.
inline void on_cancel(CancelFn func) { cancelfunc_ = func; }
/// Call a previously specified cancel callback.
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; }
/// Get the current procedure 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);
}
};

View file

@ -22,5 +22,5 @@
PrintController *print_ctl();
void set_model(Model *model);
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);
};