[Scummvm-cvs-logs] SF.net SVN: scummvm:[42399] tools/branches/gsoc2009-gui
Remere at users.sourceforge.net
Remere at users.sourceforge.net
Sun Jul 12 03:00:36 CEST 2009
Revision: 42399
http://scummvm.svn.sourceforge.net/scummvm/?rev=42399&view=rev
Author: Remere
Date: 2009-07-12 01:00:36 +0000 (Sun, 12 Jul 2009)
Log Message:
-----------
*Added functions for notifying the GUI of progress.
*You can now abort execution of a running tool, the tool will be halted the next time it prints something (or calls notifyProgress, which no tool does yet).
*Fixed bug where output paths with spaces would not open on the last page.
*Fixed bug with buttons not updating.
*Some other minor fixes.
Modified Paths:
--------------
tools/branches/gsoc2009-gui/gui/main.cpp
tools/branches/gsoc2009-gui/gui/main.h
tools/branches/gsoc2009-gui/gui/pages.cpp
tools/branches/gsoc2009-gui/gui/pages.h
tools/branches/gsoc2009-gui/tool.cpp
tools/branches/gsoc2009-gui/tool.h
tools/branches/gsoc2009-gui/util.h
Modified: tools/branches/gsoc2009-gui/gui/main.cpp
===================================================================
--- tools/branches/gsoc2009-gui/gui/main.cpp 2009-07-11 23:45:54 UTC (rev 42398)
+++ tools/branches/gsoc2009-gui/gui/main.cpp 2009-07-12 01:00:36 UTC (rev 42399)
@@ -220,6 +220,7 @@
enableNext(true);
enablePrevious(true);
showFinish(false);
+ showAbort(false);
setLineLabel(wxT("ScummVM Tools"));
}
@@ -254,6 +255,13 @@
_next->SetLabel(wxT("Next >"));
}
+void WizardButtons::showAbort(bool show) {
+ if (show)
+ _cancel->SetLabel(wxT("Abort"));
+ else
+ _cancel->SetLabel(wxT("Cancel"));
+}
+
void WizardButtons::showPrevious(bool show) {
if (show)
_prev->Show();
Modified: tools/branches/gsoc2009-gui/gui/main.h
===================================================================
--- tools/branches/gsoc2009-gui/gui/main.h 2009-07-11 23:45:54 UTC (rev 42398)
+++ tools/branches/gsoc2009-gui/gui/main.h 2009-07-12 01:00:36 UTC (rev 42399)
@@ -82,11 +82,12 @@
/** The state of the wizard so far */
Configuration _configuration;
+ /** The button pane */
+ WizardButtons *_buttons;
private:
void switchPage(WizardPage *nextPage, bool moveback);
wxPanel *_wizardpane;
- WizardButtons *_buttons;
std::vector<WizardPage *> _pages;
@@ -148,6 +149,11 @@
*/
void showFinish(bool show);
+ /**
+ * Changes name of the 'Cancel' button to abort
+ */
+ void showAbort(bool show);
+
// wx event handlers
void onClickAbout(wxCommandEvent &e);
void onClickNext(wxCommandEvent &e);
Modified: tools/branches/gsoc2009-gui/gui/pages.cpp
===================================================================
--- tools/branches/gsoc2009-gui/gui/pages.cpp 2009-07-11 23:45:54 UTC (rev 42398)
+++ tools/branches/gsoc2009-gui/gui/pages.cpp 2009-07-12 01:00:36 UTC (rev 42399)
@@ -899,7 +899,8 @@
ProcessPage::ProcessPage(ScummToolsFrame* frame)
: WizardPage(frame),
- _finished(false)
+ _finished(false),
+ _success(false)
{
}
@@ -957,6 +958,10 @@
_thread->Wait();
delete _thread;
_thread = NULL;
+ _finished = true;
+
+ // Update UI
+ updateButtons(panel, _topframe->_buttons);
return false;
}
@@ -967,16 +972,26 @@
switchPage(new FinishPage(_topframe));
}
+void ProcessPage::onCancel(wxWindow *panel) {
+ if(_finished)
+ WizardPage::onCancel(panel);
+ else
+ _thread->abort();
+}
+
void ProcessPage::updateButtons(wxWindow *panel, WizardButtons *buttons) {
if (_success) {
buttons->enablePrevious(false);
buttons->enableNext(true);
+ buttons->showAbort(false);
} else if (_finished) {
buttons->enablePrevious(true);
buttons->enableNext(true);
+ buttons->showAbort(false);
} else {
buttons->enablePrevious(false);
buttons->enableNext(false);
+ buttons->showAbort(true);
}
}
@@ -1005,6 +1020,11 @@
return NULL;
}
+void ProcessToolThread::abort() {
+ // Notify the tool of the abort
+ _tool->_backend->abort();
+}
+
void ProcessToolThread::writeToOutput(void *udata, const char *text) {
ProcessToolThread *self = reinterpret_cast<ProcessToolThread *>(udata);
@@ -1050,7 +1070,7 @@
// There is no standard way to do this
// On windows we can simply spawn an explorer instance
#ifdef __WINDOWS__
- wxExecute(wxT("explorer.exe") + _topframe->_configuration.outputPath);
+ wxExecute(wxT("explorer.exe \"") + _topframe->_configuration.outputPath + wxT("\""));
#else
#endif
}
Modified: tools/branches/gsoc2009-gui/gui/pages.h
===================================================================
--- tools/branches/gsoc2009-gui/gui/pages.h 2009-07-11 23:45:54 UTC (rev 42398)
+++ tools/branches/gsoc2009-gui/gui/pages.h 2009-07-12 01:00:36 UTC (rev 42399)
@@ -325,11 +325,16 @@
ProcessToolThread(const ToolGUI *tool, Configuration &configuration, ThreadOutputBuffer &output);
/**
- * Entry point of the subthread
+ * Entry point of the child thread.
*/
virtual ExitCode Entry();
/**
+ * Aborts execution of the thread gracefully, if possible.
+ */
+ void abort();
+
+ /**
* Write to the output window pointed to by udata, this adds
* the message to a locked queue, and prints it to the GUI from
* the main thread, as doing it from another thread can cause weird bugs.
@@ -383,6 +388,7 @@
bool onIdle(wxPanel *panel);
void onNext(wxWindow *panel);
+ void onCancel(wxWindow *panel);
void updateButtons(wxWindow *panel, WizardButtons *buttons);
};
Modified: tools/branches/gsoc2009-gui/tool.cpp
===================================================================
--- tools/branches/gsoc2009-gui/tool.cpp 2009-07-11 23:45:54 UTC (rev 42398)
+++ tools/branches/gsoc2009-gui/tool.cpp 2009-07-12 01:00:36 UTC (rev 42399)
@@ -39,6 +39,11 @@
_internalPrint = printToSTDOUT;
_print_udata = NULL;
+ _internalProgress = standardProgress;
+ _progress_udata = this;
+
+ _abort = false;
+
_helptext = "\nUsage: tool [-o outputname] <infile>\n";
}
@@ -102,7 +107,9 @@
}
void Tool::run() {
- // Not much done here, but we might want extra handling later
+ // Reset abort state
+ _abort = false;
+
execute();
}
@@ -111,6 +118,17 @@
_print_udata = udata;
}
+void Tool::setProgressFunction(void (*f)(void *, int, int), void *udata) {
+ _internalProgress = f;
+ _progress_udata = udata;
+}
+
+void Tool::abort() {
+ // Set abort safe
+ // (Non-concurrent) writes are atomic on x86
+ _abort = true;
+}
+
void Tool::error(const char *format, ...) {
char buf[4096];
va_list va;
@@ -142,8 +160,25 @@
va_end(va);
_internalPrint(_print_udata, buf);
+
+ // We notify of progress here
+ // This way, almost all tools will be able to exit gracefully (as they print stuff)
+ notifyProgress(false);
}
+void Tool::notifyProgress(bool print_dot) {
+ if(_abort)
+ throw AbortException();
+ if(print_dot)
+ _internalProgress(_progress_udata, 0, 0);
+}
+
+void Tool::updateProgress(int done, int total) {
+ if(_abort)
+ throw AbortException();
+ _internalProgress(_progress_udata, done, total);
+}
+
void Tool::parseAudioArguments() {
}
@@ -176,4 +211,10 @@
// Standard print function
void Tool::printToSTDOUT(void * /*udata*/, const char *text) {
puts(text);
-}
\ No newline at end of file
+}
+
+// Standard progress function (does nothing)
+void Tool::standardProgress(void *udata, int done, int total) {
+ if(total == 0)
+ reinterpret_cast<Tool*>(udata)->print(".");
+}
Modified: tools/branches/gsoc2009-gui/tool.h
===================================================================
--- tools/branches/gsoc2009-gui/tool.h 2009-07-11 23:45:54 UTC (rev 42398)
+++ tools/branches/gsoc2009-gui/tool.h 2009-07-12 01:00:36 UTC (rev 42399)
@@ -42,20 +42,66 @@
// passes through errors
void run();
+ /**
+ * Aborts executing of the tool, can be called from another thread
+ * The progress will not be aborted until the next call to notifyProgress
+ */
+ void abort();
+
+ /**
+ * Fatal error in the tool, throws a ToolException,
+ * you shouldn't really catch this exception.
+ */
void error(const char *format, ...);
+ /**
+ * A warning, the same as print but WARNING: is prepended to the message.
+ */
void warning(const char *format, ...);
+ /**
+ * Prints a message, to either stdout or the GUI, always use this instead of printf
+ */
void print(const char *format, ...);
/** Returns name of the tool */
std::string getName() const;
+
/**
- * This function will be called when the tool needs to output something
+ * Notifies of progress, normally just prints a dot if enough time has passed since the last call
+ * This may through an AbortException, you should generally not catch this
+ * (more than to do cleanup)
+ *
+ * @param print_dot Provides visual feedback to the user, defaults to true
+ */
+ void notifyProgress(bool print_dot = true);
+
+ /**
+ * Update progress in a more distinct way, if we know the estimated runtime
+ * This may through an AbortException, you should generally not catch this
+ * (more than to do cleanup)
+ *
+ * @param done how many parts that have been done
+ * @param total parts in total
+ */
+ void updateProgress(int done, int total = 100);
+
+ /**
+ * This function sets the function which will be called needs to output something
*
* @param f the function to be called, it takes a userdata argument in addition to text to print
* @param udata The userdata to call to the print function each time it is called
*/
void setPrintFunction(void f(void *, const char *), void *udata);
+
+ /**
+ * Set the function that is called on status updates
+ * Parameters to the function are 'done' and 'total', if total is 0,
+ * it's a simple status notification (print a dot or something)
+ *
+ * @param f this function will be called with udata arguments and 'done' / 'total'
+ * @param udata Userdata that will be passed to the function each time it is
+ */
+ void setProgressFunction(void f(void *, int, int), void *udata);
protected:
virtual void parseAudioArguments();
@@ -76,17 +122,20 @@
Filename _outputPath;
protected:
- // Command line arguments we are parsing...
+ /* Command line arguments we are parsing. */
std::vector<std::string> _arguments;
+ /* How many of the arguments we have parsed so far */
size_t _arguments_parsed;
- // We need to keep the raw arguments to invoke some functions
+ /**
+ * The raw arguments, necossary to invoke some functions properly,
+ * argc is the same as _arguments.size() */
char **_argv;
- /** If this tools outputs to a directory, not a file */
+ /** If this tools outputs to a directory, not a file. */
bool _outputToDirectory;
- /** We don't take a single file, but an entire directory as input */
+ /** We don't take a single file, but an entire directory as input .*/
bool _inputFromDirectory;
- /** */
+ /** Formats supported by this tool. */
AudioFormat _supported_formats;
/** Name of the tool */
@@ -94,11 +143,23 @@
/** The text to display to help the user */
std::string _helptext;
+ /** Status of internal abort flag, if set, next call to *Progress will throw */
+ bool _abort;
+
private:
typedef void (*PrintFunction)(void *, const char *);
PrintFunction _internalPrint;
void *_print_udata;
+
+ typedef void (*ProgressFunction)(void *, int, int);
+ ProgressFunction _internalProgress;
+ void *_progress_udata;
+
+ // Standard print function
static void printToSTDOUT(void *udata, const char *message);
+
+ // Standard progress function
+ static void standardProgress(void *udata, int done, int total);
friend class ToolGUI;
};
Modified: tools/branches/gsoc2009-gui/util.h
===================================================================
--- tools/branches/gsoc2009-gui/util.h 2009-07-11 23:45:54 UTC (rev 42398)
+++ tools/branches/gsoc2009-gui/util.h 2009-07-12 01:00:36 UTC (rev 42399)
@@ -286,6 +286,15 @@
};
/**
+ * Something unexpected happened while reading / writing to a file
+ * Usually premature end, or that it could not be opened (write / read protected)
+ */
+class AbortException : public ToolException {
+public:
+ AbortException() : ToolException("Operation was aborted", -2) {}
+};
+
+/**
* A file path, can be queried for different parts
* and the parts can be modified seperately
*/
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list