Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/non blocking for loading game info #240

Open
wants to merge 8 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 23 additions & 14 deletions source/glest_game/menu/menu_state_load_game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,11 +276,13 @@ void MenuStateLoadGame::mouseClick(int x, int y, MouseButton mouseButton){
if(slotsScrollBar.getElementCount()!=0){
for(int i = slotsScrollBar.getVisibleStart(); i <= slotsScrollBar.getVisibleEnd(); ++i) {
if(slots[i]->mouseClick(x, y) && selectedButton != slots[i]) {
loadButton.setEnabled(false);
soundRenderer.playFx(coreData.getClickSoundB());

Lang &lang= Lang::getInstance();
cleanupTexture(&previewTexture);
selectedButton = slots[i];
for(auto slot : slots) slot->setEnabled(false);
string filename = saveGameDir + selectedButton->getText()+".xml";
string screenShotFilename = filename + ".jpg";
if(fileExists(screenShotFilename) == true) {
Expand Down Expand Up @@ -317,16 +319,18 @@ void MenuStateLoadGame::mouseClick(int x, int y, MouseButton mouseButton){

#endif

XmlTree xmlTree(engine_type);

if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Before load of XML\n");
versionWarningLabel.setText("");
infoTextLabel.setText("Loading...");
std::map<string,string> mapExtraTagReplacementValues;
try {
xmlTree.load(filename, Properties::getTagReplacementValues(&mapExtraTagReplacementValues),true,false,true);

auto xmlTree = std::make_shared<XmlTree>(engine_type);
xmlTree->loadAsync(filename, Properties::getTagReplacementValues(&mapExtraTagReplacementValues),true,false,true)
->then([this, xmlTree, &lang, filename](){

if(SystemFlags::VERBOSE_MODE_ENABLED) printf("After load of XML\n");

const XmlNode *rootNode= xmlTree.getRootNode();
const XmlNode *rootNode= xmlTree->getRootNode();
if(rootNode != NULL && rootNode->hasChild("megaglest-saved-game") == true) {
rootNode = rootNode->getChild("megaglest-saved-game");
}
Expand Down Expand Up @@ -363,13 +367,18 @@ void MenuStateLoadGame::mouseClick(int x, int y, MouseButton mouseButton){
newGameSettings.getThisFactionIndex() < newGameSettings.getFactionCount() ?
newGameSettings.getFactionTypeName(newGameSettings.getThisFactionIndex()).c_str() : ""));
infoTextLabel.setText(szBuf);
for(auto slot : slots) slot->setEnabled(true);
loadButton.setEnabled(true);
});
}
catch(const megaglest_runtime_error &ex) {
char szBuf[8096]="";
snprintf(szBuf,8096,"In [%s::%s Line: %d]\nError [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what());
SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);

showMessageBox(ex.what(), lang.getString("Notice"), false);
for(auto slot : slots) slot->setEnabled(true);
loadButton.setEnabled(true);
}
}
else {
Expand All @@ -378,21 +387,21 @@ void MenuStateLoadGame::mouseClick(int x, int y, MouseButton mouseButton){

break;
}
}
}
}
}
}
}
}

void MenuStateLoadGame::mouseUp(int x, int y, const MouseButton mouseButton) {
if (mouseButton == mbLeft) {
slotsScrollBar.mouseUp(x, y);
}
if (mouseButton == mbLeft) {
slotsScrollBar.mouseUp(x, y);
}
}

void MenuStateLoadGame::mouseMove(int x, int y, const MouseState *ms) {
abortButton.mouseMove(x, y);
deleteButton.mouseMove(x, y);
loadButton.mouseMove(x, y);
abortButton.mouseMove(x, y);
deleteButton.mouseMove(x, y);
loadButton.mouseMove(x, y);
if(slotsScrollBar.getElementCount()!=0){
for(int i = slotsScrollBar.getVisibleStart(); i <= slotsScrollBar.getVisibleEnd(); ++i) {
slots[i]->mouseMove(x, y);
Expand Down
70 changes: 70 additions & 0 deletions source/shared_lib/include/util/callback.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#pragma once
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is done in other places of the code with https://github.com/MegaGlest/megaglest-source/blob/develop/source/shared_lib/include/platform/common/simple_threads.h#L71
Although honestly your way seems cleaner to me.


#include <functional>
#include <thread>
#include <utility>

using std::function;
using std::thread;

namespace Shared{ namespace Util{

template<typename T>
class CallBack {


private:
function<void()> _onThen = [](){};
function<T()> _mainFunc = [](){};
T _result;

public:
CallBack(function<T()> func){
_mainFunc = func;
};

~CallBack() {
//printf("CallBack::~CallBack p [%p]\n",this);
};

void then(function<void()> onThen){
_onThen = onThen;
};

T getResult(){
return _result;
}

void run(){
_result = _mainFunc();
_onThen();
};
};

template<>
class CallBack<void> {

private:
function<void()> _onThen = [](){};
function<void()> _mainFunc = [](){};

public:
CallBack(function<void()> func){
_mainFunc = func;
};

~CallBack() {
//printf("CallBack::~CallBack p [%p]\n",this);
};

void then(function<void()> onThen){
_onThen = onThen;
};

void run(){
_mainFunc();
_onThen();
};
};

}}
4 changes: 4 additions & 0 deletions source/shared_lib/include/xml/xml_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <string>
#include <vector>
#include <map>
#include <memory>

#if defined(WANT_XERCES)

Expand All @@ -23,10 +24,12 @@
#endif

#include "rapidxml/rapidxml.hpp"
#include "callback.h"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you forgot to include memory

#include "data_types.h"
#include "leak_dumper.h"

using namespace rapidxml;
using namespace Shared::Util;
using namespace std;

#if defined(WANT_XERCES)
Expand Down Expand Up @@ -151,6 +154,7 @@ class XmlTree{
void setSkipUpdatePathClimbingParts(bool value);
void init(const string &name);
void load(const string &path, const std::map<string,string> &mapTagReplacementValues, bool noValidation=false,bool skipStackCheck=false,bool skipStackTrace=false);
std::shared_ptr<CallBack<void>> loadAsync(const string &path, const std::map<string,string> &mapTagReplacementValues, bool noValidation=false,bool skipStackCheck=false,bool skipStackTrace=false);
void save(const string &path);

XmlNode *getRootNode() const {return rootNode;}
Expand Down
10 changes: 10 additions & 0 deletions source/shared_lib/sources/xml/xml_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,16 @@ void XmlTree::load(const string &path, const std::map<string,string> &mapTagRepl
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] about to load [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,path.c_str());
}

std::shared_ptr<CallBack<void>> XmlTree::loadAsync(const string &path, const std::map<string,string> &mapTagReplacementValues, bool noValidation,bool skipStackCheck,bool skipStackTrace) {
auto load = [this, path, mapTagReplacementValues, noValidation, skipStackCheck, skipStackTrace]() {
this->load(path, mapTagReplacementValues, noValidation, skipStackCheck, skipStackTrace);
};
auto cb = std::make_shared<CallBack<void>>(load);

std::thread([cb]() { cb->run(); }).detach();
return cb;
}

void XmlTree::save(const string &path) {

#if defined(WANT_XERCES)
Expand Down