Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#5231: Decouple ModalProgressDialog handling from the MapExporter alg…
…orithm. The MapExporter will broadcast messages for the UI to react to.
- Loading branch information
1 parent
fd67df4
commit 959f147
Showing
10 changed files
with
261 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
#pragma once | ||
|
||
#include <stdexcept> | ||
#include "imessagebus.h" | ||
|
||
namespace map | ||
{ | ||
|
||
/** | ||
* Message sent when the export code is about to start writing | ||
* to its output stream. | ||
* | ||
* If any listener wishes to cancel the operation, the cancel() | ||
* method is available, which will throw an internal exception. | ||
*/ | ||
class ExportOperation : | ||
public radiant::IMessage | ||
{ | ||
public: | ||
enum EventType | ||
{ | ||
Started, // operation started, called once | ||
Progress, // operation in progress, called 0..N times | ||
Finished, // operation finished, called once | ||
}; | ||
|
||
class OperationCancelled : | ||
public std::runtime_error | ||
{ | ||
public: | ||
OperationCancelled() : | ||
runtime_error("") | ||
{} | ||
}; | ||
|
||
private: | ||
EventType _type; | ||
float _progressFraction; | ||
std::size_t _numTotalNodes; | ||
std::string _message; | ||
|
||
public: | ||
ExportOperation(EventType type, std::size_t numTotalNodes) : | ||
ExportOperation(type, numTotalNodes, 0) | ||
{} | ||
|
||
ExportOperation(EventType type, std::size_t numTotalNodes, float progressFraction) : | ||
_type(type), | ||
_progressFraction(progressFraction), | ||
_numTotalNodes(numTotalNodes) | ||
{} | ||
|
||
const std::string& getText() const | ||
{ | ||
return _message; | ||
} | ||
|
||
void setText(const std::string& message) | ||
{ | ||
_message = message; | ||
} | ||
|
||
EventType getType() const | ||
{ | ||
return _type; | ||
} | ||
|
||
float getProgressFraction() const | ||
{ | ||
return _progressFraction; | ||
} | ||
|
||
std::size_t getNumTotalNodes() const | ||
{ | ||
return _numTotalNodes; | ||
} | ||
|
||
// Call this to cancel the ongoing export process | ||
// This will throw an exception, so control won't be returned to the caller | ||
void cancelOperation() | ||
{ | ||
throw OperationCancelled(); | ||
} | ||
}; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
#pragma once | ||
|
||
#include <memory> | ||
#include <fstream> | ||
#include <string> | ||
#include <cassert> | ||
#include "util/Noncopyable.h" | ||
|
||
namespace stream | ||
{ | ||
|
||
/** | ||
* Helper class wrapping around a std::ofstream. The instance can be empty, | ||
* until a filename is been passed to it. | ||
* | ||
* If there is a contained stream, it is ensured that it is | ||
* closed when the instance is destroyed. | ||
* | ||
* The underlying stream can be accessed through the dereference operator*() | ||
*/ | ||
class ScopedOutputStream : | ||
public std::ofstream | ||
{ | ||
private: | ||
std::unique_ptr<std::ofstream> _stream; | ||
|
||
public: | ||
// Constructs an empty stream object, no stream is opened | ||
// until the open() method is invoked | ||
ScopedFileOutputStream() | ||
{} | ||
|
||
// Constructs the wrapper and opens the internal stream | ||
// using the given filename | ||
ScopedFileOutputStream(const std::string& filename) | ||
{ | ||
open(filename); | ||
} | ||
|
||
~ScopedFileOutputStream() | ||
{ | ||
if (_stream) | ||
{ | ||
_stream->flush(); | ||
_stream->close(); | ||
_stream.reset(); | ||
} | ||
} | ||
|
||
// Returns true if there's no underlying stream object instantiated | ||
bool isEmpty() const | ||
{ | ||
return static_cast<bool>(_stream); | ||
} | ||
|
||
bool isOpen() const | ||
{ | ||
return _stream && _stream->is_open(); | ||
} | ||
|
||
std::ostream& operator*() | ||
{ | ||
assert(_stream); | ||
return *_stream; | ||
} | ||
|
||
const std::ostream& operator*() const | ||
{ | ||
assert(_stream); | ||
return *_stream; | ||
} | ||
|
||
// Open the internal stream using the given filename | ||
void open(const std::string& filename) | ||
{ | ||
assert(!_stream); // no duplicate open calls | ||
|
||
_stream.reset(new std::ofstream(filename)); | ||
} | ||
}; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
#pragma once | ||
|
||
#include "iradiant.h" | ||
#include <sigc++/functors/mem_fun.h> | ||
|
||
#include "messages/MapExportOperation.h" | ||
#include "wxutil/ModalProgressDialog.h" | ||
|
||
namespace ui | ||
{ | ||
|
||
class MapExportProgressHandler | ||
{ | ||
private: | ||
std::size_t _msgSubscription; | ||
|
||
wxutil::ModalProgressDialogPtr _dialog; | ||
|
||
public: | ||
MapExportProgressHandler() | ||
{ | ||
_msgSubscription = GlobalRadiantCore().getMessageBus().addListener( | ||
radiant::TypeListener<map::ExportOperation>( | ||
sigc::mem_fun(this, &MapExportProgressHandler::handleMapExportMessage))); | ||
} | ||
|
||
~MapExportProgressHandler() | ||
{ | ||
GlobalRadiantCore().getMessageBus().removeListener(_msgSubscription); | ||
} | ||
|
||
private: | ||
void handleMapExportMessage(map::ExportOperation& msg) | ||
{ | ||
switch (msg.getType()) | ||
{ | ||
case map::ExportOperation::Started: | ||
_dialog.reset(new wxutil::ModalProgressDialog(_("Writing map"))); | ||
break; | ||
|
||
case map::ExportOperation::Progress: | ||
if (msg.getNumTotalNodes() > 0) | ||
{ | ||
_dialog->setTextAndFraction(msg.getText(), msg.getProgressFraction()); | ||
} | ||
else | ||
{ | ||
_dialog->setText(msg.getText()); | ||
_dialog->Pulse(); | ||
} | ||
break; | ||
|
||
case map::ExportOperation::Finished: | ||
_dialog.reset(); | ||
break; | ||
}; | ||
} | ||
}; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters