[Scummvm-cvs-logs] SF.net SVN: scummvm:[42519] tools/branches/gsoc2009-gui

Remere at users.sourceforge.net Remere at users.sourceforge.net
Thu Jul 16 02:06:15 CEST 2009


Revision: 42519
          http://scummvm.svn.sourceforge.net/scummvm/?rev=42519&view=rev
Author:   Remere
Date:     2009-07-16 00:06:15 +0000 (Thu, 16 Jul 2009)

Log Message:
-----------
*Audio compression subprocess no longer spawn a console under windows, and as such does not freeze the entire desktop.
*Added support for progress bar to compress_queen.

Modified Paths:
--------------
    tools/branches/gsoc2009-gui/compress.cpp
    tools/branches/gsoc2009-gui/compress_queen.cpp
    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

Modified: tools/branches/gsoc2009-gui/compress.cpp
===================================================================
--- tools/branches/gsoc2009-gui/compress.cpp	2009-07-15 22:19:31 UTC (rev 42518)
+++ tools/branches/gsoc2009-gui/compress.cpp	2009-07-16 00:06:15 UTC (rev 42519)
@@ -144,7 +144,7 @@
 		tmp += sprintf(tmp, "-B %d ", encparms.maxBitr);
 		tmp += sprintf(tmp, "\"%s\" \"%s\" ", inname, outname);
 
-		err = system(fbuf) != 0;
+		err = spawnSubprocess(fbuf) != 0;
 
 		if (err) {
 			char buf[2048];
@@ -187,7 +187,7 @@
 			tmp += sprintf(tmp, "--output=\"%s\" ", outname);
 			tmp += sprintf(tmp, "\"%s\" ", inname);
 
-			err = system(fbuf) != 0;
+			err = spawnSubprocess(fbuf) != 0;
 
 			if (err) {
 				char buf[2048];35xk'x25uk
@@ -227,7 +227,7 @@
 			tmp += sprintf(tmp, "-o \"%s\" ", outname);
 			tmp += sprintf(tmp, "\"%s\" ", inname);
 
-			err = system(fbuf) != 0;
+			err = spawnSubprocess(fbuf) != 0;
 
 			if (err) {
 				char buf[2048];

Modified: tools/branches/gsoc2009-gui/compress_queen.cpp
===================================================================
--- tools/branches/gsoc2009-gui/compress_queen.cpp	2009-07-15 22:19:31 UTC (rev 42518)
+++ tools/branches/gsoc2009-gui/compress_queen.cpp	2009-07-16 00:06:15 UTC (rev 42519)
@@ -91,6 +91,7 @@
 
 CompressQueen::CompressQueen(const std::string &name) : CompressionTool(name) {
 	_outputToDirectory = false;
+	_supportsProgressBar = true;
 
 	_helptext = "\nUsage: %s [mode] [mode params] [-o outputfile] <inputfile (queen.1)>\n" kCompressionAudioHelp;
 }
@@ -215,6 +216,9 @@
 	outputTbl.writeUint16BE(_versionExtra.entries);
 
 	for (i = 0; i < _versionExtra.entries; i++) {
+		/* Update progress */
+		updateProgress(i, _versionExtra.entries);
+
 		prevOffset = outputData.pos();
 
 		/* Read entry */

Modified: tools/branches/gsoc2009-gui/gui/pages.cpp
===================================================================
--- tools/branches/gsoc2009-gui/gui/pages.cpp	2009-07-15 22:19:31 UTC (rev 42518)
+++ tools/branches/gsoc2009-gui/gui/pages.cpp	2009-07-16 00:06:15 UTC (rev 42519)
@@ -32,6 +32,7 @@
 
 #include <wx/filepicker.h>
 #include <wx/file.h>
+#include <wx/process.h>
 
 #include "main.h"
 #include "pages.h"
@@ -281,7 +282,7 @@
 
 void ChooseInPage::onNext(wxWindow *panel) {
 	if (_configuration.advanced) {
-		if(_configuration.selectedTool->_inputs.size() > 1)
+		if (_configuration.selectedTool->_inputs.size() > 1)
 			switchPage(new ChooseExtraInPage(_topframe));
 		else
 			switchPage(new ChooseOutPage(_topframe));
@@ -365,7 +366,7 @@
 
 	// Remove all additional inputs
 	wxArrayString filelist = _configuration.inputFilePaths;
-	if(filelist.size() > 1)
+	if (filelist.size() > 1)
 		filelist.erase(filelist.begin() + 1, filelist.end());
 
 	int i = 1;
@@ -907,6 +908,10 @@
 
 	_output.done = 0;
 	_output.total = 100;
+
+	_output.cmd = NULL;
+	_output.retval = 0;
+	_output.subprocessFinished = NULL;
 }
 
 wxWindow *ProcessPage::CreatePanel(wxWindow *parent) {
@@ -955,6 +960,7 @@
 	if (!_thread)
 		return false;
 
+	// Check if our subthread has something for us to do
 	{
 		wxMutexLocker lock(_output.mutex);
 
@@ -962,11 +968,22 @@
 		_outwin->WriteText(wxString(_output.buffer.c_str(), wxConvUTF8));
 		_output.buffer = "";
 
-		if(tool->supportsProgressBar()) {
+		if (tool->supportsProgressBar()) {
 			// Update gauge
 			_gauge->SetRange(_output.total);
 			_gauge->SetValue(_output.done);
 		}
+
+		if (_output.cmd) {
+			// We have a waiting subprocess to run, the other thread is sleeping since we could lock the mutex
+			
+			wxProcess proc(wxPROCESS_REDIRECT);
+			_output.retval = wxExecute(wxString(_output.cmd, wxConvUTF8), wxEXEC_SYNC, &proc);
+			_output.cmd = NULL;
+
+			// Signal the other thread that we have run the subprocess
+			_output.subprocessFinished->Signal();
+		}
 	}
 
 	// Check if thread finished
@@ -982,7 +999,7 @@
 		return false;
 	}
 
-	if(!tool->supportsProgressBar()) {
+	if (!tool->supportsProgressBar()) {
 		// Just move the bar back & forth
 		_gauge->Pulse();
 	}
@@ -991,14 +1008,14 @@
 }
 
 void ProcessPage::onNext(wxWindow *panel) {
-	if(_success)
+	if (_success)
 		switchPage(new FinishPage(_topframe));
 	else
 		switchPage(new FailurePage(_topframe));
 }
 
 void ProcessPage::onCancel(wxWindow *panel) {
-	if(_finished)
+	if (_finished)
 		WizardPage::onCancel(panel);
 	else
 		_thread->abort();
@@ -1029,7 +1046,7 @@
 
 // The thread a tool is run in
 
-ProcessToolThread::ProcessToolThread(const ToolGUI *tool, Configuration &configuration, ThreadOutputBuffer &output) : 
+ProcessToolThread::ProcessToolThread(const ToolGUI *tool, Configuration &configuration, ThreadCommunicationBuffer &output) : 
 	wxThread(wxTHREAD_JOINABLE), 
 	_configuration(configuration),
 	_output(output) 
@@ -1039,6 +1056,7 @@
 	
 	_tool->_backend->setPrintFunction(writeToOutput, reinterpret_cast<void *>(this));
 	_tool->_backend->setProgressFunction(gaugeProgress, reinterpret_cast<void *>(this));
+	_tool->_backend->setSubprocessFunction(spawnSubprocess, reinterpret_cast<void *>(this));
 }
 
 wxThread::ExitCode ProcessToolThread::Entry() {
@@ -1073,6 +1091,26 @@
 	self->_output.total = total;
 }
 
+int ProcessToolThread::spawnSubprocess(void *udata, const char *cmd) {
+	ProcessToolThread *self = reinterpret_cast<ProcessToolThread *>(udata);
+	
+	wxASSERT_MSG(self->_output.subprocessFinished == NULL, wxT("You can only spawn one subprocess."));
+
+	wxMutexLocker mutex(self->_output.mutex);
+	self->_output.subprocessFinished = new wxCondition(self->_output.mutex);
+	self->_output.cmd = cmd;
+
+	// Wait for the other thread, this unlocks the mutex
+	self->_output.subprocessFinished->Wait();
+	// Mutex is locked again after wait, so we can clear safely
+
+	// Cleanup the condition
+	delete self->_output.subprocessFinished;
+	self->_output.subprocessFinished = NULL;
+
+	return self->_output.retval;
+}
+
 // Last page of the wizard, offers the option to open the output directory
 
 FinishPage::FinishPage(ScummToolsFrame* frame)

Modified: tools/branches/gsoc2009-gui/gui/pages.h
===================================================================
--- tools/branches/gsoc2009-gui/gui/pages.h	2009-07-15 22:19:31 UTC (rev 42518)
+++ tools/branches/gsoc2009-gui/gui/pages.h	2009-07-16 00:06:15 UTC (rev 42519)
@@ -311,10 +311,20 @@
  * & child thread to update it
  */
 
-struct ThreadOutputBuffer {
+struct ThreadCommunicationBuffer {
 	std::string buffer;
 	int done;
 	int total;
+
+	// Subprocesses can only be spawned from the main thread
+	// Commands are exchanged with the main thread here
+	// If cmd is not NULL when the main thread is checking, the buffer is locked
+	// The subprocess is spawned and waited for exit, the cmd is set to NULL and retval
+	// is set to the return value of the subprocess.
+	const char *cmd;
+	int retval;
+	wxCondition *subprocessFinished;
+
 	wxMutex mutex;
 };
 
@@ -324,7 +334,7 @@
 
 class ProcessToolThread : public wxThread {
 public:
-	ProcessToolThread(const ToolGUI *tool, Configuration &configuration, ThreadOutputBuffer &output);
+	ProcessToolThread(const ToolGUI *tool, Configuration &configuration, ThreadCommunicationBuffer &output);
 
 	/**
 	 * Entry point of the child thread.
@@ -350,13 +360,18 @@
 	 */
 	static void gaugeProgress(void *udata, int done, int total);
 
+	/**
+	 * Spawns a subprocess without GUI
+	 */
+	static int spawnSubprocess(void *udata, const char *cmd);
+
 	bool _finished;
 
 protected:
 	/** The current configuration */
 	Configuration &_configuration;
 	/** */
-	ThreadOutputBuffer &_output;
+	ThreadCommunicationBuffer &_output;
 	/** */
 	const ToolGUI *_tool;
 };
@@ -381,7 +396,7 @@
 	/** The thread which the tool is run in */
 	ProcessToolThread *_thread;
 	/** The structure to exchange output between thread & gui */
-	ThreadOutputBuffer _output;
+	ThreadCommunicationBuffer _output;
 
 public:
 	ProcessPage(ScummToolsFrame* frame);

Modified: tools/branches/gsoc2009-gui/tool.cpp
===================================================================
--- tools/branches/gsoc2009-gui/tool.cpp	2009-07-15 22:19:31 UTC (rev 42518)
+++ tools/branches/gsoc2009-gui/tool.cpp	2009-07-16 00:06:15 UTC (rev 42519)
@@ -37,12 +37,15 @@
 	_supportedFormats = AUDIO_NONE;
 	_supportsProgressBar = false;
 
-	_internalPrint = printToSTDOUT;
+	_internalPrint = standardPrint;
 	_print_udata = NULL;
 
 	_internalProgress = standardProgress;
 	_progress_udata = this;
 
+	_internalSubprocess = standardSpawnSubprocess;
+	_subprocess_udata = NULL;
+
 	_abort = false;
 
 	_helptext = "\nUsage: tool [-o outputname] <infile>\n";
@@ -124,6 +127,15 @@
 	_progress_udata = udata;
 }
 
+void Tool::setSubprocessFunction(int (*f)(void *, const char *), void *udata) {
+	_internalSubprocess = f;
+	_subprocess_udata = udata;
+}
+
+int Tool::spawnSubprocess(const char *cmd) {
+	return _internalSubprocess(_subprocess_udata, cmd);
+}
+
 void Tool::abort() {
 	// Set abort safe
 	// (Non-concurrent) writes are atomic on x86
@@ -168,14 +180,14 @@
 }
 
 void Tool::notifyProgress(bool print_dot) {
-	if(_abort)
+	if (_abort)
 		throw AbortException();
-	if(print_dot)
+	if (print_dot)
 		_internalProgress(_progress_udata, 0, 0);
 }
 
 void Tool::updateProgress(int done, int total) {
-	if(_abort)
+	if (_abort)
 		throw AbortException();
 	_internalProgress(_progress_udata, done, total);
 }
@@ -210,12 +222,15 @@
 }
 
 // Standard print function
-void Tool::printToSTDOUT(void * /*udata*/, const char *text) {
+void Tool::standardPrint(void * /*udata*/, const char *text) {
 	puts(text);
 }
 
 // Standard progress function (does nothing)
 void Tool::standardProgress(void *udata, int done, int total) {
-	if(total == 0)
-		reinterpret_cast<Tool*>(udata)->print(".");
 }
+
+// Standard subprocess function
+int Tool::standardSpawnSubprocess(void *udata, const char *cmd) {
+	return system(cmd);
+}

Modified: tools/branches/gsoc2009-gui/tool.h
===================================================================
--- tools/branches/gsoc2009-gui/tool.h	2009-07-15 22:19:31 UTC (rev 42518)
+++ tools/branches/gsoc2009-gui/tool.h	2009-07-16 00:06:15 UTC (rev 42519)
@@ -1,3 +1,4 @@
+
 /* tool.h - Common base class for all tools
  * Copyright (C) 2009 The ScummVM project
  *
@@ -86,6 +87,14 @@
 	void updateProgress(int done, int total = 100);
 
 	/**
+	 * Spawns a subprocess with the given commandline
+	 * this acts exactly the same as 'system()', but hides the process window
+	 *
+	 * @param cmd The commandline to run
+	 */
+	int spawnSubprocess(const char *cmd);
+
+	/**
 	 * 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
@@ -99,10 +108,20 @@
 	 * 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 
+	 * @param udata Userdata that will be passed to the function on each call
 	 */
 	void setProgressFunction(void f(void *, int, int), void *udata);
 
+	/**
+	 * Sets the function to use to execute a process
+	 * this defaults to the function 'system()', GUI overloads this
+	 * to not spawn a window.
+	 *
+	 * @param f this function will be called when a process needs to be spawned
+	 * @param udata Userdata that will be passed to the function on each call
+	 */
+	void setSubprocessFunction(int f(void *, const char *), void *udata);
+
 protected:
 	virtual void parseAudioArguments();
 	void parseOutputArguments();
@@ -157,12 +176,20 @@
 	ProgressFunction _internalProgress;
 	void *_progress_udata;
 
+
+	typedef int (*SubprocessFunction)(void *, const char *);
+	SubprocessFunction _internalSubprocess;
+	void *_subprocess_udata;
+
 	// Standard print function
-	static void printToSTDOUT(void *udata, const char *message);
+	static void standardPrint(void *udata, const char *message);
 	
 	// Standard progress function
 	static void standardProgress(void *udata, int done, int total);
 
+	// Standard subprocess function
+	static int standardSpawnSubprocess(void *udata, const char *);
+
 	friend class ToolGUI;
 };
 


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