Get rid of direct references to emulation thread in branchesmenu.cpp
This commit is contained in:
parent
6bad138d8b
commit
d7c6cd1905
6 changed files with 164 additions and 75 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue