mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-12 13:37:00 -04:00
Added thread-safety to thumbnail request system.
Marked symbol requests as not being thread-safe. Added icon to symbol editor Made *.* actually register on * git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@407 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
@@ -33,7 +33,7 @@ String import_formats() {
|
|||||||
type_strings += _("|") + f->name() + _("|*.") + f->extension();
|
type_strings += _("|") + f->name() + _("|*.") + f->extension();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return _("Set files|") + all_extensions + type_strings + _("|All files (*.*)|*.*");
|
return _("Set files|") + all_extensions + type_strings + _("|All files (*.*)|*");
|
||||||
}
|
}
|
||||||
|
|
||||||
String export_formats(const Game& game) {
|
String export_formats(const Game& game) {
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ void export_mws(Window* parent, const SetP& set) {
|
|||||||
|
|
||||||
// Select filename
|
// Select filename
|
||||||
String name = wxFileSelector(_("Export to file"),_(""),_(""),_(""),
|
String name = wxFileSelector(_("Export to file"),_(""),_(""),_(""),
|
||||||
_("Text files (*.txt)|*.txt|All Files|*.*"),
|
_("Text files (*.txt)|*.txt|All Files|*"),
|
||||||
wxSAVE | wxOVERWRITE_PROMPT, parent);
|
wxSAVE | wxOVERWRITE_PROMPT, parent);
|
||||||
if (name.empty()) return;
|
if (name.empty()) return;
|
||||||
wxBusyCursor busy;
|
wxBusyCursor busy;
|
||||||
|
|||||||
@@ -45,6 +45,9 @@ class GeneratedImage : public ScriptValue {
|
|||||||
/// Equality should mean that every pixel in the generated images is the same if the same options are used
|
/// Equality should mean that every pixel in the generated images is the same if the same options are used
|
||||||
virtual bool operator == (const GeneratedImage& that) const = 0;
|
virtual bool operator == (const GeneratedImage& that) const = 0;
|
||||||
inline bool operator != (const GeneratedImage& that) const { return !(*this == that); }
|
inline bool operator != (const GeneratedImage& that) const { return !(*this == that); }
|
||||||
|
|
||||||
|
/// Can this image be generated safely from another thread?
|
||||||
|
virtual bool threadSafe() const = 0;
|
||||||
|
|
||||||
virtual ScriptType type() const;
|
virtual ScriptType type() const;
|
||||||
virtual String typeName() const;
|
virtual String typeName() const;
|
||||||
@@ -61,6 +64,8 @@ class LinearBlendImage : public GeneratedImage {
|
|||||||
virtual Image generate(const Options& opt) const;
|
virtual Image generate(const Options& opt) const;
|
||||||
virtual ImageCombine combine() const;
|
virtual ImageCombine combine() const;
|
||||||
virtual bool operator == (const GeneratedImage& that) const;
|
virtual bool operator == (const GeneratedImage& that) const;
|
||||||
|
|
||||||
|
virtual bool threadSafe() const {return true;}
|
||||||
private:
|
private:
|
||||||
GeneratedImageP image1, image2;
|
GeneratedImageP image1, image2;
|
||||||
double x1, y1, x2, y2;
|
double x1, y1, x2, y2;
|
||||||
@@ -77,6 +82,8 @@ class MaskedBlendImage : public GeneratedImage {
|
|||||||
virtual Image generate(const Options& opt) const;
|
virtual Image generate(const Options& opt) const;
|
||||||
virtual ImageCombine combine() const;
|
virtual ImageCombine combine() const;
|
||||||
virtual bool operator == (const GeneratedImage& that) const;
|
virtual bool operator == (const GeneratedImage& that) const;
|
||||||
|
|
||||||
|
virtual bool threadSafe() const {return true;}
|
||||||
private:
|
private:
|
||||||
GeneratedImageP light, dark, mask;
|
GeneratedImageP light, dark, mask;
|
||||||
};
|
};
|
||||||
@@ -92,6 +99,8 @@ class CombineBlendImage : public GeneratedImage {
|
|||||||
virtual Image generate(const Options& opt) const;
|
virtual Image generate(const Options& opt) const;
|
||||||
virtual ImageCombine combine() const;
|
virtual ImageCombine combine() const;
|
||||||
virtual bool operator == (const GeneratedImage& that) const;
|
virtual bool operator == (const GeneratedImage& that) const;
|
||||||
|
|
||||||
|
virtual bool threadSafe() const {return true;}
|
||||||
private:
|
private:
|
||||||
GeneratedImageP image1, image2;
|
GeneratedImageP image1, image2;
|
||||||
ImageCombine image_combine;
|
ImageCombine image_combine;
|
||||||
@@ -108,6 +117,8 @@ class SetMaskImage : public GeneratedImage {
|
|||||||
virtual Image generate(const Options& opt) const;
|
virtual Image generate(const Options& opt) const;
|
||||||
virtual ImageCombine combine() const;
|
virtual ImageCombine combine() const;
|
||||||
virtual bool operator == (const GeneratedImage& that) const;
|
virtual bool operator == (const GeneratedImage& that) const;
|
||||||
|
|
||||||
|
virtual bool threadSafe() const {return true;}
|
||||||
private:
|
private:
|
||||||
GeneratedImageP image, mask;
|
GeneratedImageP image, mask;
|
||||||
};
|
};
|
||||||
@@ -123,6 +134,8 @@ class SetCombineImage : public GeneratedImage {
|
|||||||
virtual Image generate(const Options& opt) const;
|
virtual Image generate(const Options& opt) const;
|
||||||
virtual ImageCombine combine() const;
|
virtual ImageCombine combine() const;
|
||||||
virtual bool operator == (const GeneratedImage& that) const;
|
virtual bool operator == (const GeneratedImage& that) const;
|
||||||
|
|
||||||
|
virtual bool threadSafe() const {return true;}
|
||||||
private:
|
private:
|
||||||
GeneratedImageP image;
|
GeneratedImageP image;
|
||||||
ImageCombine image_combine;
|
ImageCombine image_combine;
|
||||||
@@ -138,6 +151,8 @@ class PackagedImage : public GeneratedImage {
|
|||||||
{}
|
{}
|
||||||
virtual Image generate(const Options& opt) const;
|
virtual Image generate(const Options& opt) const;
|
||||||
virtual bool operator == (const GeneratedImage& that) const;
|
virtual bool operator == (const GeneratedImage& that) const;
|
||||||
|
|
||||||
|
virtual bool threadSafe() const {return true;}
|
||||||
private:
|
private:
|
||||||
String filename;
|
String filename;
|
||||||
};
|
};
|
||||||
@@ -152,6 +167,8 @@ class BuiltInImage : public GeneratedImage {
|
|||||||
{}
|
{}
|
||||||
virtual Image generate(const Options& opt) const;
|
virtual Image generate(const Options& opt) const;
|
||||||
virtual bool operator == (const GeneratedImage& that) const;
|
virtual bool operator == (const GeneratedImage& that) const;
|
||||||
|
|
||||||
|
virtual bool threadSafe() const {return true;}
|
||||||
private:
|
private:
|
||||||
String name;
|
String name;
|
||||||
};
|
};
|
||||||
@@ -165,6 +182,8 @@ class SymbolToImage : public GeneratedImage {
|
|||||||
~SymbolToImage();
|
~SymbolToImage();
|
||||||
virtual Image generate(const Options& opt) const;
|
virtual Image generate(const Options& opt) const;
|
||||||
virtual bool operator == (const GeneratedImage& that) const;
|
virtual bool operator == (const GeneratedImage& that) const;
|
||||||
|
|
||||||
|
virtual bool threadSafe() const {return false;}
|
||||||
private:
|
private:
|
||||||
SymbolToImage(const SymbolToImage&); // copy ctor
|
SymbolToImage(const SymbolToImage&); // copy ctor
|
||||||
String filename;
|
String filename;
|
||||||
|
|||||||
@@ -84,6 +84,8 @@ class CardThumbnailRequest : public ThumbnailRequest {
|
|||||||
parent->Refresh(false);
|
parent->Refresh(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool threadSafe() const {return true;}
|
||||||
private:
|
private:
|
||||||
String filename;
|
String filename;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ class PackageList : public GalleryList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Shows packages that match a specific patern
|
/// Shows packages that match a specific patern
|
||||||
void showData(const String& pattern = _("*.*"));
|
void showData(const String& pattern = _("*"));
|
||||||
|
|
||||||
/// Clears this list
|
/// Clears this list
|
||||||
void clear();
|
void clear();
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ void ImagesExportWindow::onOk(wxCommandEvent&) {
|
|||||||
ScriptP filename_script = parse(gs.images_export_filename, true);
|
ScriptP filename_script = parse(gs.images_export_filename, true);
|
||||||
// Select filename
|
// Select filename
|
||||||
String name = wxFileSelector(_TITLE_("export images"),_(""), _LABEL_("filename is ignored"),_(""),
|
String name = wxFileSelector(_TITLE_("export images"),_(""), _LABEL_("filename is ignored"),_(""),
|
||||||
_LABEL_("filename is ignored")+_("|*.*"), wxSAVE, this);
|
_LABEL_("filename is ignored")+_("|*"), wxSAVE, this);
|
||||||
if (name.empty()) return;
|
if (name.empty()) return;
|
||||||
wxFileName fn(name);
|
wxFileName fn(name);
|
||||||
// Export
|
// Export
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ SymbolWindow::SymbolWindow(Window* parent, const SymbolValueP& value, const SetP
|
|||||||
|
|
||||||
void SymbolWindow::init(Window* parent, SymbolP symbol) {
|
void SymbolWindow::init(Window* parent, SymbolP symbol) {
|
||||||
Create(parent, wxID_ANY, _TITLE_("symbol editor"), wxDefaultPosition, wxSize(600,600), wxDEFAULT_FRAME_STYLE | wxNO_FULL_REPAINT_ON_RESIZE);
|
Create(parent, wxID_ANY, _TITLE_("symbol editor"), wxDefaultPosition, wxSize(600,600), wxDEFAULT_FRAME_STYLE | wxNO_FULL_REPAINT_ON_RESIZE);
|
||||||
|
SetIcon(load_resource_icon(_("app")));
|
||||||
inSelectionEvent = false;
|
inSelectionEvent = false;
|
||||||
|
|
||||||
// Menu bar
|
// Menu bar
|
||||||
|
|||||||
@@ -130,17 +130,41 @@ void ThumbnailThread::request(const ThumbnailRequestP& request) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
request_names.insert(request);
|
if (request->threadSafe()) {
|
||||||
// request generation
|
request_names.insert(request);
|
||||||
{
|
// request generation
|
||||||
wxMutexLocker lock(mutex);
|
{
|
||||||
open_requests.push_back(request);
|
wxMutexLocker lock(mutex);
|
||||||
|
open_requests.push_back(request);
|
||||||
|
}
|
||||||
|
// is there a worker?
|
||||||
|
if (!worker) {
|
||||||
|
worker = new ThumbnailThreadWorker(this);
|
||||||
|
worker->Create();
|
||||||
|
worker->Run();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// is there a worker?
|
else {
|
||||||
if (!worker) {
|
Image img;
|
||||||
worker = new ThumbnailThreadWorker(this);
|
try {
|
||||||
worker->Create();
|
img = request->generate();
|
||||||
worker->Run();
|
} catch (const Error& e) {
|
||||||
|
handle_error(e, false, false);
|
||||||
|
} catch (...) {
|
||||||
|
}
|
||||||
|
// store in cache
|
||||||
|
if (img.Ok()) {
|
||||||
|
String filename = image_cache_dir() + safe_filename(request->cache_name) + _(".png");
|
||||||
|
img.SaveFile(filename, wxBITMAP_TYPE_PNG);
|
||||||
|
// set modification time
|
||||||
|
wxFileName fn(filename);
|
||||||
|
fn.SetTimes(0, &request->modified, 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
wxMutexLocker lock(mutex);
|
||||||
|
closed_requests.push_back(make_pair(request,img));
|
||||||
|
completed.Signal();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,9 @@ class ThumbnailRequest : public IntrusivePtrVirtualBase {
|
|||||||
virtual Image generate() = 0;
|
virtual Image generate() = 0;
|
||||||
/// Store the thumbnail, called from the main thread
|
/// Store the thumbnail, called from the main thread
|
||||||
virtual void store(const Image&) = 0;
|
virtual void store(const Image&) = 0;
|
||||||
|
|
||||||
|
/// Can the thumbnail safely be generated from another thread?
|
||||||
|
virtual bool threadSafe() const = 0;
|
||||||
|
|
||||||
/// Object that requested the thumbnail
|
/// Object that requested the thumbnail
|
||||||
void* const owner;
|
void* const owner;
|
||||||
|
|||||||
@@ -23,6 +23,9 @@ class ChoiceThumbnailRequest : public ThumbnailRequest {
|
|||||||
ChoiceThumbnailRequest(ValueViewer* cve, int id, bool from_disk);
|
ChoiceThumbnailRequest(ValueViewer* cve, int id, bool from_disk);
|
||||||
virtual Image generate();
|
virtual Image generate();
|
||||||
virtual void store(const Image&);
|
virtual void store(const Image&);
|
||||||
|
|
||||||
|
bool isThreadSafe;
|
||||||
|
virtual bool threadSafe() const {return isThreadSafe;}
|
||||||
private:
|
private:
|
||||||
StyleSheetP stylesheet;
|
StyleSheetP stylesheet;
|
||||||
int id;
|
int id;
|
||||||
@@ -37,7 +40,12 @@ ChoiceThumbnailRequest::ChoiceThumbnailRequest(ValueViewer* cve, int id, bool fr
|
|||||||
)
|
)
|
||||||
, stylesheet(cve->viewer.stylesheet)
|
, stylesheet(cve->viewer.stylesheet)
|
||||||
, id(id)
|
, id(id)
|
||||||
{}
|
{
|
||||||
|
ChoiceValueEditor& e = *(ChoiceValueEditor*)cve;
|
||||||
|
String name = cannocial_name_form(e.field().choices->choiceName(id));
|
||||||
|
ScriptableImage& img = e.style().choice_images[name];
|
||||||
|
isThreadSafe = img.threadSafe();
|
||||||
|
}
|
||||||
|
|
||||||
Image ChoiceThumbnailRequest::generate() {
|
Image ChoiceThumbnailRequest::generate() {
|
||||||
ChoiceValueEditor& cve = *(ChoiceValueEditor*)owner;
|
ChoiceValueEditor& cve = *(ChoiceValueEditor*)owner;
|
||||||
|
|||||||
@@ -45,6 +45,9 @@ class ScriptableImage {
|
|||||||
inline void initDependencies(Context& ctx, const Dependency& dep) const {
|
inline void initDependencies(Context& ctx, const Dependency& dep) const {
|
||||||
script.initDependencies(ctx, dep);
|
script.initDependencies(ctx, dep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Can this be safely generated from another thread?
|
||||||
|
bool threadSafe() const {return value->threadSafe();}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OptionalScript script; ///< The script, not really optional
|
OptionalScript script; ///< The script, not really optional
|
||||||
|
|||||||
Reference in New Issue
Block a user