Get rid of direct references to emulation thread in branchesmenu.cpp

This commit is contained in:
Ilari Liusvaara 2014-05-31 18:16:05 +03:00
parent 6bad138d8b
commit d7c6cd1905
6 changed files with 164 additions and 75 deletions

View file

@ -13,6 +13,7 @@ class memwatch_set;
class controller_state;
class button_mapping;
class emulator_dispatch;
class input_queue;
namespace command
{
class group;
@ -169,7 +170,7 @@ class project_state
public:
project_state(voice_commentary& _commentary, memwatch_set& _mwatch, command::group& _command,
controller_state& _controls, settingvar::cache& _setcache, button_mapping& _buttons,
emulator_dispatch& _edispatch);
emulator_dispatch& _edispatch, input_queue& _iqueue);
~project_state();
/**
* Get currently active project.
@ -223,6 +224,49 @@ public:
* Copy macros to project.
*/
void copy_macros(project_info& p, controller_state& s);
/**
* Fill branch name map.
*
* Notes: Safe to call from another thread.
*/
void F_get_branch_map(uint64_t& cur, std::map<uint64_t, std::string>& namemap,
std::map<uint64_t, std::set<uint64_t>>& childmap);
/**
* Arrange current project to be flushed later.
*
* Notes: Safe to call from another thread.
*/
void F_call_flush(std::function<void(std::exception&)> onerror);
/**
* Arrage branch to be created.
*
* Notes: Safe to call from another thread.
*/
void F_create_branch(uint64_t id, const std::string& name, std::function<void(std::exception&)> onerror);
/**
* Arrage branch to be renamed.
*
* Notes: Safe to call from another thread.
*/
void F_rename_branch(uint64_t id, const std::string& name, std::function<void(std::exception&)> onerror);
/**
* Arrage branch to be reparented.
*
* Notes: Safe to call from another thread.
*/
void F_reparent_branch(uint64_t id, uint64_t pid, std::function<void(std::exception&)> onerror);
/**
* Arrage branch to be deleted.
*
* Notes: Safe to call from another thread.
*/
void F_delete_branch(uint64_t id, std::function<void(std::exception&)> onerror);
/**
* Arrage branch to be switched.
*
* Notes: Safe to call from another thread.
*/
void F_switch_branch(uint64_t id, std::function<void(std::exception&)> onerror);
private:
project_info* active_project;
voice_commentary& commentary;
@ -232,6 +276,7 @@ private:
settingvar::cache& setcache;
button_mapping& buttons;
emulator_dispatch& edispatch;
input_queue& iqueue;
};
#endif

View file

@ -107,6 +107,7 @@ void show_message_ok(wxWindow* parent, const std::string& title, const std::stri
bool run_show_error(wxWindow* parent, const std::string& title, const std::string& text, std::function<void()> fn);
void show_exception(wxWindow* parent, const std::string& title, const std::string& text, std::exception& e);
void show_exception_any(wxWindow* parent, const std::string& title, const std::string& text, std::exception& e);
//Some important windows (if open).
extern wxwin_messages* msg_window;

View file

@ -68,6 +68,8 @@ emulator_instance::emulator_instance()
D.prealloc(buttons);
D.init(dispatch);
D.init(command);
D.init(iqueue, *command);
D.init(mlogic);
D.init(memory);
D.init(lua);
@ -79,7 +81,6 @@ emulator_instance::emulator_instance()
D.init(mbranch, *mlogic, *dispatch);
D.init(controls, *project, *mlogic, *buttons, *dispatch);
D.init(keyboard);
D.init(command);
D.init(mapper, *keyboard, *command);
D.init(fbuf, *subtitles, *settings, *mwatch, *keyboard, *dispatch);
D.init(buttons, *controls, *mapper, *keyboard, *fbuf, *dispatch);
@ -91,10 +92,9 @@ emulator_instance::emulator_instance()
D.init(abindmanager, *mapper, *command);
D.init(nrrdata);
D.init(cmapper, *memory, *mlogic);
D.init(project, *commentary, *mwatch, *command, *controls, *setcache, *buttons, *dispatch);
D.init(project, *commentary, *mwatch, *command, *controls, *setcache, *buttons, *dispatch, *iqueue);
D.init(dbg, *dispatch);
D.init(framerate);
D.init(iqueue, *command);
D.init(mdumper);
status_A->valid = false;

View file

@ -9,6 +9,7 @@
#include "core/moviedata.hpp"
#include "core/moviefile.hpp"
#include "core/project.hpp"
#include "core/queue.hpp"
#include "library/directory.hpp"
#include "library/minmax.hpp"
#include "library/string.hpp"
@ -24,6 +25,16 @@ void do_flush_slotinfo();
namespace
{
void fill_namemap(project_info& p, uint64_t id, std::map<uint64_t, std::string>& namemap,
std::map<uint64_t, std::set<uint64_t>>& childmap)
{
namemap[id] = p.get_branch_name(id);
auto s = p.branch_children(id);
for(auto i : s)
fill_namemap(p, i, namemap, childmap);
childmap[id] = s;
}
void concatenate(std::vector<char>& data, const std::vector<char>& app)
{
size_t dsize = data.size();
@ -188,9 +199,9 @@ namespace
project_state::project_state(voice_commentary& _commentary, memwatch_set& _mwatch, command::group& _command,
controller_state& _controls, settingvar::cache& _setcache, button_mapping& _buttons,
emulator_dispatch& _edispatch)
emulator_dispatch& _edispatch, input_queue& _iqueue)
: commentary(_commentary), mwatch(_mwatch), command(_command), controls(_controls), setcache(_setcache),
buttons(_buttons), edispatch(_edispatch)
buttons(_buttons), edispatch(_edispatch), iqueue(_iqueue)
{
active_project = NULL;
}
@ -479,6 +490,80 @@ void project_state::copy_macros(project_info& p, controller_state& s)
p.macros[i] = s.get_macro(i).serialize();
}
void project_state::F_get_branch_map(uint64_t& cur, std::map<uint64_t, std::string>& namemap,
std::map<uint64_t, std::set<uint64_t>>& childmap)
{
iqueue.run([this, &cur, &namemap, &childmap]() {
auto p = this->get();
if(!p) return;
fill_namemap(*p, 0, namemap, childmap);
cur = p->get_current_branch();
});
}
void project_state::F_call_flush(std::function<void(std::exception&)> onerror)
{
iqueue.run_async([this]() {
auto p = this->get();
if(p) p->flush();
}, onerror);
}
void project_state::F_create_branch(uint64_t id, const std::string& name,
std::function<void(std::exception&)> onerror)
{
iqueue.run_async([this, id, name]() {
auto p = this->get();
if(!p) return;
p->create_branch(id, name);
p->flush();
}, onerror);
}
void project_state::F_rename_branch(uint64_t id, const std::string& name,
std::function<void(std::exception&)> onerror)
{
iqueue.run_async([this, id, name]() {
auto p = this->get();
if(!p) return;
p->set_branch_name(id, name);
p->flush();
update_movie_state();
}, onerror);
}
void project_state::F_reparent_branch(uint64_t id, uint64_t pid, std::function<void(std::exception&)> onerror)
{
iqueue.run_async([this, id, pid]() {
auto p = this->get();
if(!p) return;
p->set_parent_branch(id, pid);
p->flush();
update_movie_state();
}, onerror);
}
void project_state::F_delete_branch(uint64_t id, std::function<void(std::exception&)> onerror)
{
iqueue.run_async([this, id]() {
auto p = this->get();
if(!p) return;
p->delete_branch(id);
p->flush();
}, onerror);
}
void project_state::F_switch_branch(uint64_t id, std::function<void(std::exception&)> onerror)
{
iqueue.run_async([this, id]() {
auto p = this->get();
if(!p) return;
p->set_current_branch(id);
p->flush();
update_movie_state();
}, onerror);
}
project_info::project_info(emulator_dispatch& _dispatch)
: edispatch(_dispatch)
{
@ -530,6 +615,8 @@ void project_info::set_parent_branch(uint64_t bid, uint64_t pbid)
throw std::runtime_error("Invalid branch ID");
if(pbid && !branches.count(pbid))
throw std::runtime_error("Invalid parent branch ID");
if(bid == pbid)
throw std::runtime_error("Branch can't be its own parent");
for(auto& i : branches) {
uint64_t j = i.first;
while(j) {

View file

@ -13,16 +13,6 @@ void update_movie_state();
namespace
{
void fill_namemap(project_info& p, uint64_t id, std::map<uint64_t, std::string>& namemap,
std::map<uint64_t, std::set<uint64_t>>& childmap)
{
namemap[id] = p.get_branch_name(id);
auto s = p.branch_children(id);
for(auto i : s)
fill_namemap(p, i, namemap, childmap);
childmap[id] = s;
}
//Tree of branches.
class branches_tree : public wxTreeCtrl
{
@ -68,12 +58,7 @@ namespace
std::map<uint64_t, std::string> namemap;
std::map<uint64_t, std::set<uint64_t>> childmap;
uint64_t cur = 0;
lsnes_instance.iqueue->run([&cur, &namemap, &childmap]() {
auto p = lsnes_instance.project->get();
if(!p) return;
fill_namemap(*p, 0, namemap, childmap);
cur = p->get_current_branch();
});
lsnes_instance.project->F_get_branch_map(cur, namemap, childmap);
current = cur;
selection cursel = get_selection();
std::set<uint64_t> expanded;
@ -103,13 +88,6 @@ namespace
return names[id];
return "";
}
void call_project_flush()
{
lsnes_instance.iqueue->run_async([] {
auto p = CORE().project->get();
if(p) p->flush();
}, [](std::exception& e) {});
}
private:
void build_tree(uint64_t id, wxTreeItemId parent, std::map<uint64_t, std::set<uint64_t>>& childmap,
std::map<uint64_t, std::string>& namemap)
@ -236,26 +214,17 @@ namespace
} catch(canceled_exception& e) {
return;
}
lsnes_instance.iqueue->run([this, id, newname]() {
run_show_error(this, "Error creating branch", "Can't create branch", [id, newname]() {
auto p = CORE().project->get();
if(p) p->create_branch(id, newname);
});
lsnes_instance.project->F_create_branch(id, newname, [this](std::exception& e) {
show_exception_any(this, "Error creating branch", "Can't create branch", e);
});
branches->call_project_flush();
}
void on_select(wxCommandEvent& e)
{
uint64_t id = get_selected_id();
if(id == 0xFFFFFFFFFFFFFFFFULL) return;
lsnes_instance.iqueue->run([this, id]() {
run_show_error(this, "Error setting branch", "Can't set branch", [id]() {
auto p = CORE().project->get();
if(p) p->set_current_branch(id);
});
lsnes_instance.project->F_switch_branch(id, [this](std::exception& e) {
show_exception_any(this, "Error setting branch", "Can't set branch", e);
});
branches->call_project_flush();
update_movie_state();
}
void on_rename(wxCommandEvent& e)
{
@ -268,14 +237,9 @@ namespace
} catch(canceled_exception& e) {
return;
}
lsnes_instance.iqueue->run([this, id, newname]() {
run_show_error(this, "Error renaming branch", "Can't rename branch", [id, newname]() {
auto p = CORE().project->get();
if(p) p->set_branch_name(id, newname);
});
lsnes_instance.project->F_rename_branch(id, newname, [this](std::exception& e) {
show_exception_any(this, "Error renaming branch", "Can't rename branch", e);
});
branches->call_project_flush();
update_movie_state();
}
void on_reparent(wxCommandEvent& e)
{
@ -291,27 +255,17 @@ namespace
pid = bsel->get_selection();
if(pid == 0xFFFFFFFFFFFFFFFFULL) return;
bsel->Destroy();
lsnes_instance.iqueue->run([this, id, pid]() {
run_show_error(this, "Error reparenting branch", "Can't reparent branch",
[id, pid]() {
auto p = CORE().project->get();
if(p) p->set_parent_branch(id, pid);
});
lsnes_instance.project->F_reparent_branch(id, pid, [this](std::exception& e) {
show_exception_any(this, "Error reparenting branch", "Can't reparent branch", e);
});
branches->call_project_flush();
update_movie_state();
}
void on_delete(wxCommandEvent& e)
{
uint64_t id = get_selected_id();
if(id == 0xFFFFFFFFFFFFFFFFULL) return;
lsnes_instance.iqueue->run([this, id]() {
run_show_error(this, "Error deleting branch", "Can't delete branch", [id]() {
auto p = CORE().project->get();
if(p) p->delete_branch(id);
});
lsnes_instance.project->F_delete_branch(id, [this](std::exception& e) {
show_exception_any(this, "Error deleting branch", "Can't delete branch", e);
});
branches->call_project_flush();
}
void on_close(wxCommandEvent& e)
{
@ -407,13 +361,8 @@ void branches_menu::on_select(wxCommandEvent& e)
if(!branch_ids.count(id)) return;
uint64_t bid = branch_ids[id];
std::string err;
lsnes_instance.iqueue->run_async([this, bid]() {
auto p = CORE().project->get();
if(p) p->set_current_branch(bid);
if(p) p->flush();
update_movie_state();
}, [this](std::exception& e) {
show_exception(this->pwin, "Error changing branch", "Can't change branch", e);
lsnes_instance.project->F_switch_branch(bid, [this](std::exception& e) {
show_exception_any(this->pwin, "Error changing branch", "Can't change branch", e);
});
}
@ -421,11 +370,8 @@ void branches_menu::update()
{
std::map<uint64_t, std::string> namemap;
std::map<uint64_t, std::set<uint64_t>> childmap;
lsnes_instance.iqueue->run([&namemap, &childmap]() {
auto p = CORE().project->get();
if(!p) return;
fill_namemap(*p, 0, namemap, childmap);
});
uint64_t cur;
lsnes_instance.project->F_get_branch_map(cur, namemap, childmap);
//First destroy everything that isn't a menu.
for(auto i : otheritems)
i.parent->Delete(i.item);

View file

@ -753,3 +753,13 @@ void show_exception(wxWindow* parent, const std::string& title, const std::strin
std::string _text = (text == "") ? err : (text + ": " + err);
show_message_ok(parent, _title, _text, wxICON_EXCLAMATION);
}
void show_exception_any(wxWindow* parent, const std::string& title, const std::string& text, std::exception& e)
{
std::string err = e.what();
std::string _title = title;
std::string _text = (text == "") ? err : (text + ": " + err);
runuifun([parent, _title, _text]() {
show_message_ok(parent, _title, _text, wxICON_EXCLAMATION);
});
}