Commit 798d6782 authored by Loic Guegan's avatar Loic Guegan
Browse files

Add engine configuration

parent 1529283e
Pipeline #216128340 failed with stage
in 7 minutes and 42 seconds
......@@ -13,6 +13,11 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") # Be hard-liner
########## DEPENDENCIES ##########
# Find boost
find_package(Boost 1.65 REQUIRED COMPONENTS log log_setup) # Logging component need to be explicitely specified :(
add_definitions(-DBOOST_LOG_DYN_LINK=1) # To avoid linker error on DEBIAN (cf: https://stackoverflow.com/questions/23137637/linker-error-while-linking-boost-log-tutorial-undefined-references)
include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})
# Find wxwidget
set(LOCAL_WX "${CMAKE_CURRENT_BINARY_DIR}/WX")
if(EXISTS "${LOCAL_WX}")
message(STATUS "Using local WxWidgets ${LOCAL_WX}")
......@@ -22,16 +27,10 @@ if(EXISTS "${LOCAL_WX}")
else()
message(STATUS "Note that you can use your own local WxWidgets project by placing it into ${LOCAL_WX}. Thus, WxWidgets should be compiled in ${LOCAL_WX}/build.")
endif()
find_package(Boost 1.65 REQUIRED COMPONENTS log log_setup) # Logging component need to be explicitely specified :(
add_definitions(-DBOOST_LOG_DYN_LINK=1) # To avoid linker error on DEBIAN (cf: https://stackoverflow.com/questions/23137637/linker-error-while-linking-boost-log-tutorial-undefined-references)
include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})
# Find wxwidget
find_package(wxWidgets REQUIRED COMPONENTS core base)
find_package(wxWidgets COMPONENTS core base propgrid REQUIRED)
include(${wxWidgets_USE_FILE})
include_directories(${wxWidgets_INCLUDE_DIRS})
link_directories(${wxWidgets_LIBRARIES_DIRS})
########## SRC ##########
# Define variables
set(SRC ${CMAKE_SOURCE_DIR}/src)
......
#include "MainFrame.hpp"
namespace ochess {
namespace gui {
......@@ -33,7 +34,8 @@ wxFrame(NULL, wxID_ANY, title, pos, size) {
SetMenuBar(menuBar);
// Create required windows
Create(WIN_BOARD);
Create(WIN_SETTINGS);
//new EngineSelection(this);
// Setup status bar
CreateStatusBar();
......
......@@ -10,11 +10,115 @@
namespace ochess {
namespace gui {
EngineSettings::EngineSettings(wxWindow* parent):wxPanel(parent,wxID_ANY,wxDefaultPosition) {
wxStaticText* pieceLabel=new wxStaticText(this, wxID_ANY, "Engine");
wxBoxSizer *VBox=new wxBoxSizer(wxVERTICAL);
// Engine list
wxStaticText* engineListLabel=new wxStaticText(this, wxID_ANY, "Engine list");
wxFont font=engineListLabel->GetFont().Bold();
engineListLabel->SetFont(font);
VBox->Add(engineListLabel);
EngineList=new wxListCtrl(this,wxID_ANY,wxDefaultPosition,wxSize(-1,150),wxLC_REPORT);
EngineList->AppendColumn("Name");
EngineList->AppendColumn("Type");
VBox->Add(EngineList,0,wxEXPAND|wxTOP,10);
this->Bind(wxEVT_LIST_ITEM_DESELECTED,&EngineSettings::EngineListHandler,this);
this->Bind(wxEVT_LIST_ITEM_SELECTED,&EngineSettings::EngineListHandler,this);
wxBoxSizer *HBox=new wxBoxSizer(wxHORIZONTAL);
wxButton *Add = new wxButton(this, 124, "Add");
Delete = new wxButton(this, 125, "Delete");
Delete->Disable();
HBox->AddStretchSpacer();
HBox->Add(Delete);
HBox->Add(Add,0,wxLEFT,5);
VBox->Add(HBox,0,wxEXPAND|wxTOP,10);
this->Bind(wxEVT_BUTTON, &EngineSettings::ButtonHandler, this);
// Engine configuration
wxStaticText* optionLabel=new wxStaticText(this, wxID_ANY, "Options");
optionLabel->SetFont(font);
VBox->Add(optionLabel,0,wxEXPAND|wxTOP,10);
EngineConf = new wxPropertyGrid(this,wxID_ANY,wxDefaultPosition,wxSize(-1,150));
VBox->Add(EngineConf,0,wxEXPAND|wxTOP,10);
this->SetSizer(VBox);
Config=CNF.GetPtree("engines");
ConfigureEngineList();
}
void EngineSettings::Apply(){
}
void EngineSettings::SetupEngineConf(string engine){
EngineConf->Clear();
string optPath="list."+engine+".options";
std::cout << "Path: " << optPath << std::endl << std::flush;
ptree opt_list=Config.get_child(optPath);
for (const ptree::value_type& opt : opt_list) {
string optName=opt.first;
string curOptPath=optPath+"."+optName;
string value=Config.get<string>(curOptPath+".value");
string type=Config.get<string>(curOptPath+".type");
if(type=="spin"){
wxIntProperty * prop=new wxIntProperty(optName, optName, std::stoi(value));
prop->SetAttribute("Min", Config.get<string>(curOptPath+".min"));
prop->SetAttribute("Max", Config.get<string>(curOptPath+".max"));
EngineConf->Append(prop);
}
else if(type=="check"){
wxBoolProperty * prop=new wxBoolProperty(optName, optName, value=="true");
EngineConf->Append(prop);
}
else if(type=="combo"){
wxArrayString choices;
for (const ptree::value_type& choice : Config.get_child(curOptPath+".var")) {
choices.push_back(Config.get<string>(curOptPath+".var."+choice.first));
}
wxEnumProperty *prop=new wxEnumProperty(optName,optName,choices);
EngineConf->Append(prop);
}
else{
wxStringProperty * prop=new wxStringProperty(optName, optName, value);
EngineConf->Append(prop);
}
}
}
void EngineSettings::ButtonHandler(wxCommandEvent &event){
if(event.GetId()==125){
int id=EngineList->GetNextItem(-1,wxLIST_NEXT_ALL,wxLIST_STATE_SELECTED);
if(id!=-1){
Config.get_child("list").erase(to_string(id));
EngineList->DeleteItem(id);
Delete->Disable();
}
}
else if (event.GetId()==124){
EngineSel=new EngineSelection(this);
EngineSel->Subscribe(this);
EngineSel->ShowModal();
}
}
void EngineSettings::ConfigureEngineList(){
int id=0;
while(id>=0){
id=EngineList->GetNextItem(-1,wxLIST_NEXT_ALL,wxLIST_STATE_DONTCARE);
if(id>=0)
EngineList->DeleteItem(id);
}
ptree engine_list=Config.get_child("list");
int i=0;
for (const ptree::value_type& engine : engine_list) {
string path="list."+engine.first;
EngineList->InsertItem(i, Config.get<string>(path+".name"));
EngineList->SetItem(i, 1, Config.get<string>(path+".name"));
EngineList->SetItemData(i,std::stoi(engine.first));
i++;
}
}
} /* namespace gui */
} /* namespace ochess */
......@@ -12,14 +12,137 @@
#include <wx/wx.h>
#endif
#include "Applicable.hpp"
#include <wx/listctrl.h>
#include "ochess.hpp"
#include <boost/foreach.hpp>
#include <wx/propgrid/propgrid.h>
#include <wx/propgrid/property.h>
#include <wx/propgrid/advprops.h>
#include <wx/filectrl.h>
#include "engine/Engine.hpp"
#include "utils/observer/Subject.hpp"
#include "utils/observer/Observer.hpp"
#include <algorithm>
using namespace ochess::engine;
namespace ochess {
namespace gui {
class EngineSettings: public wxPanel, public Applicable{
class EngineSelection: public Subject, public wxDialog {
wxFileCtrl *FileSelect;
public:
EngineSettings(wxWindow* parent);
EngineSelection(wxWindow *parent) :
wxDialog(parent, -1, "Board Settings", wxDefaultPosition,
wxSize(800, 600)) {
wxBoxSizer *TopSizer = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *VBox = new wxBoxSizer(wxVERTICAL);
FileSelect =
new wxFileCtrl(this, wxID_ANY,
"/home/loic/.local/bin/source/scid_vs_pc/engines/stockfish10/Linux/", //wxEmptyString, // Default directory
wxEmptyString, // Default filename
wxFileSelectorDefaultWildcardStr,
wxFC_DEFAULT_STYLE, wxDefaultPosition,
wxSize(800, 500));
VBox->Add(FileSelect);
wxBoxSizer *HBox = new wxBoxSizer(wxHORIZONTAL);
wxButton *Ok = new wxButton(this, 654, "Ok");
wxButton *Cancel = new wxButton(this, 23, "Cancel");
this->Bind(wxEVT_BUTTON, &EngineSelection::ButtonHandler, this);
HBox->AddStretchSpacer();
HBox->Add(Cancel, 0);
HBox->Add(Ok, 0, wxLEFT, 10);
VBox->Add(HBox, 0, wxEXPAND | wxTOP, 20);
TopSizer->Add(VBox, 0, wxALL, 10);
this->SetSizer(TopSizer);
this->Bind(wxEVT_CLOSE_WINDOW, &EngineSelection::OnClose, this);
}
string GetEnginePath() {
return (FileSelect->GetPath().ToStdString());
}
void ButtonHandler(wxCommandEvent &event) {
if (event.GetId() == 654) {
NotifyAll(SBJ_ENGINE_SELECTED);
this->Close();
} else if (event.GetId() == 23)
this->Close();
}
void OnClose(wxCloseEvent &event) {
this->Destroy();
}
};
class EngineSettings: public wxPanel, public Applicable, public Observer {
wxListCtrl *EngineList;
wxPropertyGrid *EngineConf;
ptree Config;
EngineSelection *EngineSel;
wxButton *Delete;
private:
void SetupEngineConf(string engine);
public:
EngineSettings(wxWindow *parent);
void Apply() override;
void ConfigureEngineList();
void EngineListHandler(wxListEvent &event) {
if (event.GetEventType() == wxEVT_LIST_ITEM_DESELECTED)
Delete->Disable();
else {
Delete->Enable();
std::cout << "Update:" << std::to_string(event.GetItem().GetData())
<< std::flush << std::endl;
SetupEngineConf(std::to_string(event.GetItem().GetData()));
}
//std::cout << event.GetIndex() << std::endl;
}
void Notify(SUBJECT sbj) override {
if (sbj == SBJ_ENGINE_SELECTED) {
string engine = EngineSel->GetEnginePath();
if (engine.size() != 0) {
Engine e(engine);
std::map<std::string, UCI_OPT> options = e.GetOptions();
// Find next engine ID
int id = 0;
bool found = true;
while (found) {
found = false;
for (const ptree::value_type &engine : Config.get_child(
"list")) {
found = (engine.first == std::to_string(id));
if (found)
break;
}
id++;
}
// Add engine to config
string path = "list." + std::to_string(id);
Config.put(path + ".name", "NewEngine");
Config.put(path + ".options", "EngineOptions");
for (auto pair : options) {
string curOpt = path + ".options." + pair.first;
curOpt.erase(std::remove(curOpt.begin(), curOpt.end(), ' '),
curOpt.end());
Config.put(curOpt + ".type", pair.second.type);
Config.put(curOpt + ".value", pair.second.value);
Config.put(curOpt + ".min", pair.second.min);
Config.put(curOpt + ".max", pair.second.max);
int i=0;
for(string pairVar: pair.second.var){
Config.put(curOpt + ".var."+std::to_string(i),pairVar);
i++;
}
}
e.quit();
ConfigureEngineList();
}
}
}
void ButtonHandler(wxCommandEvent &event);
};
} /* namespace gui */
......
......@@ -28,10 +28,11 @@ Settings::Settings(wxFrame *parent) :
MenuTree *menu=new MenuTree(MainPanel,wxSize(200,500));
MenuTreeModel *model=new MenuTreeModel();
MenuTreeNode* entry=model->CreateEntry("General",0);
MenuTreeNode* selected=entry;
MenuTreeNode* selected;
entry=model->CreateEntry("Board",1);
model->CreateSubEntry(entry,"Appearance",2);
entry=model->CreateEntry("Engine",3);
selected=entry;
menu->AssociateModel(model);
for(auto item:model->GetItems()) // Expand everything
menu->Expand(item);
......@@ -52,7 +53,7 @@ Settings::Settings(wxFrame *parent) :
EngineSettings* es=new EngineSettings(Book);
ToApply.push_back(es);
Book->AddPage(es,"Engine");
Book->ChangeSelection(0);
Book->ChangeSelection(3);
// Setup MainPanel sizers
wxBoxSizer *HBox=new wxBoxSizer(wxHORIZONTAL);
......
......@@ -31,15 +31,35 @@ ConfigManager::ConfigManager() {
}
}
// Init configurations
InitDefaultBoardView();
}
void ConfigManager::InitDefaultBoardView(){
// Default board configuration
CNF_DEFAULT("board_view.theme.pieces",string,"cburnett");
CNF_DEFAULT("board_view.theme.board",string,"chesscom_green");
CNF_DEFAULT("engines.list.0.name",string,"stockfish");
CNF_DEFAULT("engines.list.0.options.MultiPV.type",string,"spin");
CNF_DEFAULT("engines.list.0.options.MultiPV.value",string,"5");
CNF_DEFAULT("engines.list.0.options.MultiPV.min",string,"0");
CNF_DEFAULT("engines.list.0.options.MultiPV.max",string,"5");
CNF_DEFAULT("engines.list.0.options.Jean.type",string,"check");
CNF_DEFAULT("engines.list.0.options.Jean.value",string,"5");
CNF_DEFAULT("engines.list.0.options.Name.type",string,"string");
CNF_DEFAULT("engines.list.0.options.Name.value",string,"5");
CNF_DEFAULT("engines.list.0.options.Pierre.type",string,"combo");
CNF_DEFAULT("engines.list.0.options.Pierre.value",string,"level1");
CNF_DEFAULT("engines.list.0.options.Pierre.var.0",string,"level1");
CNF_DEFAULT("engines.list.0.options.Pierre.var.2",string,"level2");
CNF_DEFAULT("engines.list.0.options.Pierre.var.3",string,"level3");
CNF_DEFAULT("engines.list.1.name",string,"komodo");
CNF_DEFAULT("engines.list.1.options",string,"test");
}
void ConfigManager::Apply() {
json_parser::write_json(ConfigFile.string(), Configuration);
NotifyAll(SBJ_CNF);
......
......@@ -37,8 +37,6 @@ class ConfigManager : public Subject{
/// @brief Contains the loaded application configuration
ptree Configuration;
void InitDefaultBoardView();
public:
ConfigManager();
......@@ -54,9 +52,15 @@ public:
template<typename T>
T Get(string path){
// TODO: Handle error
return(Configuration.get<T>(path));
}
ptree GetPtree(string path){
// TODO: Handle error
return(Configuration.get_child(path));
}
template<typename T>
void Set(string path, T value){
Configuration.put<T>(path, value);
......
......@@ -12,7 +12,8 @@ namespace ochess {
typedef enum SUBJECT {
SBJ_UNKNOWN,
SBJ_CNF
SBJ_CNF,
SBJ_ENGINE_SELECTED
}SUBJECT;
class Observer {
......
......@@ -16,12 +16,14 @@ Subject::Subject(SUBJECT insight) :
}
Subject::Subject() :
Insight(SBJ_UNKNOWN) {
}
void Subject::NotifyAll() {
NotifyAll(this->Insight);
}
void Subject::Bob() {
std::cout << Observers.size() << std::endl;
}
void Subject::NotifyAll(SUBJECT insight) {
for (auto obs : Observers) {
obs->Notify(insight);
......
......@@ -24,6 +24,7 @@ private:
protected:
void NotifyAll(SUBJECT insight);
void NotifyAll();
void Bob();
public:
Subject(SUBJECT insight);
Subject();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment