Commit ebb5abf8 authored by Loic Guegan's avatar Loic Guegan
Browse files

Integrate log and scrolling

parent 54c1f360
......@@ -13,7 +13,7 @@ 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 :(
find_package(Boost 1.65 REQUIRED COMPONENTS log log_setup program_options) # 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})
......
......@@ -22,16 +22,22 @@ void PGNEditor::Render(State *state) {
this->MaxY = 1;
this->MinX = 0;
this->MinY = 0;
if(state->MouseClick){
this->LastMouseClickX=state->mouseX;
this->LastMouseClickY=state->mouseY;
}
// Start Drawing
this->DrawHintBar();
if(state->moveline != nullptr)
this->DrawLine(state->moveline);
this->DrawScrollBars();
state->MouseClick=false;
}
void PGNEditor::DrawHintBar() {
Shape hintBar(0, 0, state->hintBarWidth, canvasH);
Shape hintBar(0, -state->offsetY, state->hintBarWidth, canvasH);
hintBar.target = Shape::HINTBAR;
DrawCall(hintBar);
}
......@@ -55,20 +61,55 @@ void PGNEditor::DrawScrollBars() {
double VSSize = (double) canvasH
* ((double) canvasH / std::max(canvasH, MaxY - MinY));
Shape HS(state->offsetX, canvasH, HSSize, state->scrollbarThickness);
Shape HS(-state->offsetX, canvasH, HSSize, state->scrollbarThickness);
HS.target = Shape::SCROLLBAR_H;
Shape VS(canvasW, state->offsetY, state->scrollbarThickness, VSSize);
Shape VS(canvasW, -state->offsetY, state->scrollbarThickness, VSSize);
VS.target = Shape::SCROLLBAR_V;
if(state->IsDragging){
if(LastMouseClickOnHS){
state->offsetX-=(state->mouseX-LastMouseClickX);
LastMouseClickX=state->mouseX;
state->offsetX=-std::min(std::max(0,-state->offsetX),state->canvasW);
if(std::abs(state->offsetX)>=(canvasW-HSSize))
state->offsetX=-(canvasW-HSSize);
else if(state->offsetX>=0)
state->offsetX=0;
}
if(LastMouseClickOnVS){
state->offsetY-=(state->mouseY-LastMouseClickY);
LastMouseClickY=state->mouseY;
if(std::abs(state->offsetY)>=(canvasH-VSSize))
state->offsetY=-(canvasH-VSSize);
else if(state->offsetY>=0)
state->offsetY=0;
}
}
// Check mouse over
if (HS.x <= state->mouseX && HS.y <= state->mouseY
&& (HS.x + HSSize) >= state->mouseX
&& (HS.y + state->scrollbarThickness) >= state->mouseY)
&& (HS.y + state->scrollbarThickness) >= state->mouseY){
HS.mouseHover = true;
HS.mouseClick=state->MouseClick;
}
if (VS.x <= state->mouseX && VS.y <= state->mouseY
&& (VS.x + state->scrollbarThickness) >= state->mouseX
&& (VS.y + VSSize) >= state->mouseY)
&& (VS.y + VSSize) >= state->mouseY){
VS.mouseHover = true;
VS.mouseClick=state->MouseClick;
}
if(state->MouseClick){
LastMouseClickOnHS=(state->MouseClick && HS.mouseHover);
LastMouseClickOnVS=(state->MouseClick && VS.mouseHover);
}
Draw(HS);
Draw(VS);
......@@ -176,8 +217,10 @@ void PGNEditor::DrawCall(Shape shape) {
MinY = shape.y;
if (shape.x <= state->mouseX && shape.y <= state->mouseY
&& maxX >= state->mouseX && maxY >= state->mouseY)
&& maxX >= state->mouseX && maxY >= state->mouseY){
shape.mouseHover = true;
shape.mouseClick=state->MouseClick;
}
// Issue a draw only if necessary
if (shape.x <= canvasW && shape.y <= canvasH)
......
......@@ -25,6 +25,11 @@ private:
int LineCount;
int CurrentX;
int CurrentY;
int LastMouseClickX;
int LastMouseClickY;
bool LastMouseClickOnHS;
bool LastMouseClickOnVS;
int CurrentVSY;
/// @brief Used by scrollbars
int MaxX,MinX;
......@@ -40,6 +45,10 @@ private:
protected:
void Render(State *state);
virtual void Draw(Shape shape) = 0;
public:
PGNEditor():LastMouseClickOnHS(false),LastMouseClickOnVS(false){
}
};
} /* namespace ochess */
......
......@@ -38,15 +38,16 @@ public:
TYPE type;
TARGET target;
bool mouseHover;
bool mouseClick;
Shape(double x,double y,double w, double h):
x(x),y(y),w(w),h(h),radius(0),type(RECTANGLE),target(NA),mouseHover(false){
x(x),y(y),w(w),h(h),radius(0),type(RECTANGLE),target(NA),mouseHover(false),mouseClick(false){
}
Shape(std::string text, double x,double y):
x(x),y(y),w(0),h(0),radius(0),text(text),type(TEXT),target(NA),mouseHover(false){
x(x),y(y),w(0),h(0),radius(0),text(text),type(TEXT),target(NA),mouseHover(false),mouseClick(false){
}
Shape(double x,double y, double radius):
x(x),y(y),w(0),h(0),radius(radius),type(CIRCLE),target(NA),mouseHover(false){
x(x),y(y),w(0),h(0),radius(radius),type(CIRCLE),target(NA),mouseHover(false),mouseClick(false){
}
int GetWidth(State* state){
......
......@@ -17,6 +17,9 @@ public:
bool WhiteToPlay;
int mouseX, mouseY;
int canvasW, canvasH;
/// @brief This value is automatically reset by the editor
bool MouseClick;
bool IsDragging;
/// @brief How much units variations should be shifted to the right
int variationOffset;
......@@ -25,11 +28,11 @@ public:
/// @brief Used by the scroll feature
int offsetX,offsetY;
int scrollbarThickness;
// @brief Font size in px
/// @brief Font size in px
int fontSize;
int topMargin,leftMargin;
int hintBarWidth;
// @brief Size of the move counter column
/// @brief Size of the move counter column
int counterW;
int varationSepW;
......@@ -52,6 +55,8 @@ public:
hintBarWidth=30;
counterW=20;
varationSepW=5;
MouseClick=false;
IsDragging=false;
}
};
......
......@@ -35,7 +35,7 @@ void UCIProc::InitializeEngine(){
InitSuccess = EngineProc.running();
if (!InitSuccess)
LOG(ERROR)
LOG(error)
<< "Failed to init engine: " << EnginePath;
}
......@@ -45,7 +45,7 @@ UCIProc::~UCIProc() {
Chrono delay;
while (IsAlive()) {
if (delay.Milliseconds() > 1000) { // Let it 1s to stop
LOG(WARNING)
LOG(info)
<< "Killing engine!";
EngineProc.terminate();
break;
......
......@@ -117,6 +117,7 @@ void BoardPanel::HandleMouse(wxMouseEvent &event) {
boost::optional<Coord> square = C.GetSquareAt(pos.x, pos.y);
if (square && UA->DraggingPieceSquare) {
if (UA->DraggingPieceSquare.value() != square.value()) {
LOG(debug) << "Trying to play move "<< UA->DraggingPieceSquare.value().GetXY() << " to " << square.value().GetXY();
C.Move(UA->DraggingPieceSquare.value(), square.value());
/// @todo Optimize call to isCheckMate
if (C.G.IsCheckMate(ochess::model::BLACK)) {
......
......@@ -12,6 +12,7 @@
#include <boost/thread/mutex.hpp>
#include "ochess.hpp"
#include "utils/observer/Observer.hpp"
#include "log.hpp"
using namespace ochess::model;
......
......@@ -21,7 +21,7 @@ void BoardController::Move(Coord src, Coord dst) {
if (state.ActiveColor == ochess::model::BLACK) {
BlackEngine->position("fen " + G.GetFen());
BlackEngine->go(false, false);
LOG(INFO)
LOG(info)
<< "Engine is thinking...";
while (!BlackEngine->IsBestMoveFound()) {
}
......
......@@ -7,13 +7,13 @@ Skin::Skin() {
wxInitAllImageHandlers();
for (auto &theme : CNF.ListPiecesThemes()) {
LOG(TRACE)
LOG(trace)
<< "Loading default pieces skin: " << theme;
LoadPiecesSkin(theme);
break;
}
for (auto &theme : CNF.ListBoardThemes()) {
LOG(TRACE)
LOG(trace)
<< "Loading default board skin: " << theme;
LoadSquaresSkin(theme);
break;
......
......@@ -10,6 +10,10 @@
namespace ochess {
namespace gui {
BEGIN_EVENT_TABLE(Editor, wxPanel)
EVT_MOUSE_EVENTS(Editor::MouseEvent)
END_EVENT_TABLE()
Editor::Editor(wxFrame *parent) :
wxPanel(parent), DC(nullptr) {
this->Bind(wxEVT_PAINT, &Editor::OnPaint, this);
......@@ -25,12 +29,15 @@ Editor::Editor(wxFrame *parent) :
this->Bind(wxEVT_CHAR_HOOK, &Editor::OnKeyDown, this);
this->Bind(wxEVT_MOTION, &Editor::MouseMove, this);
}
void Editor::OnKeyDown(wxKeyEvent &event) {
Refresh();
}
void Editor::MouseMove(wxMouseEvent &event) {
void Editor::MouseEvent(wxMouseEvent &event) {
if(event.LeftDown()){
state->MouseClick=true;
}
state->IsDragging=event.Dragging();
Refresh();
}
void Editor::OnPaint(wxPaintEvent &event) {
......
......@@ -11,6 +11,8 @@
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
#include <wx/event.h>
#include "editor/PGNEditor.hpp"
......@@ -27,7 +29,8 @@ public:
void OnPaint(wxPaintEvent& event);
void Draw(Shape shape) override;
void OnKeyDown(wxKeyEvent& event);
void MouseMove(wxMouseEvent& event);
void MouseEvent(wxMouseEvent &event);
DECLARE_EVENT_TABLE()
};
} /* namespace gui */
......
......@@ -14,7 +14,7 @@ EngineView::EngineView() :
void EngineView::OnClose(wxCloseEvent &event) {
(void) event;
LOG(WARNING)
LOG(warning)
<< "Delete";
this->Show(false);
}
......
......@@ -18,8 +18,9 @@
#include <boost/move/utility_core.hpp>
#include <boost/log/sources/global_logger_storage.hpp>
#include <fstream>
#include <boost/log/support/date_time.hpp>
#define LOG(level) BOOST_LOG_SEV(ochess_logger::get(),level)
#define LOG(level) BOOST_LOG_SEV(ochess_logger::get(),logging::trivial::level)
namespace logging = boost::log;
......@@ -29,26 +30,21 @@ namespace bfs = boost::filesystem;
namespace expr = boost::log::expressions;
namespace attrs = boost::log::attributes;
BOOST_LOG_ATTRIBUTE_KEYWORD(engine_path, "EnginePath", std::string);
BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(ochess_logger, src::severity_logger_mt<>)
namespace ochess {
typedef enum LOG_LEVELS{
TRACE=boost::log::trivial::trace,
DEBUG=boost::log::trivial::debug,
INFO=boost::log::trivial::info,
WARNING=boost::log::trivial::warning,
ERROR=boost::log::trivial::error,
fatal=boost::log::trivial::fatal
} LOG_LEVELS;
BOOST_LOG_ATTRIBUTE_KEYWORD(engine_path, "EnginePath", std::string);
BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", logging::trivial::severity_level)
BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(ochess_logger, src::severity_logger_mt<logging::trivial::severity_level>)
inline void OC_INIT_LOG() {
inline void OC_INIT_LOG(bool trace) {
#ifdef NDEBUG
boost::log::core::get()->set_filter(boost::log::trivial::severity >
boost::log::trivial::debug);
#else
if(!trace){
boost::log::core::get()->set_filter(boost::log::trivial::severity > // @suppress("Invalid arguments")
boost::log::trivial::trace);
}
#endif
bfs::path logPath = CNF.GetLogPath();
......@@ -75,19 +71,18 @@ inline void OC_INIT_LOG() {
ochessSink->locked_backend()->add_stream( // @suppress("Invalid arguments")
boost::make_shared<std::ofstream>(
(logPath / "ochess.txt").string()));
boost::shared_ptr< std::ostream > stream(&std::clog, boost::null_deleter());
ochessSink->locked_backend()->add_stream(stream);// @suppress("Invalid arguments")
ochessSink->locked_backend()->auto_flush(true);
ochessSink->set_formatter(
expr::stream << "["
<< expr::attr<boost::posix_time::ptime>("TimeStamp")
<< "]> " << expr::smessage);
<< expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "%Y-%m-%d %H:%M:%S")
<< " (" << logging::trivial::severity << ")] " << expr::smessage);
ochessSink->set_filter(!expr::has_attr(engine_path));
// Configure logs
logging::core::get()->add_sink(engineSink); // @suppress("Invalid arguments")
logging::core::get()->add_sink(ochessSink); // @suppress("Invalid arguments")
logging::add_console_log(std::cout, logging::keywords::filter =
!expr::has_attr(engine_path), logging::keywords::format =
"[%TimeStamp%]> %Message%");
}
} // namespace ochess
......
......@@ -186,7 +186,7 @@ template<class T> bool Board<T>::move(Coord src, Coord dst) {
dst_s->isEmpty = false;
return true;
}
LOG(WARNING)
LOG(warning)
<< "You are trying to move a piece that do not exist on board: "
<< src.GetXY() << " to " << dst.GetXY();
return false;
......
......@@ -89,7 +89,7 @@ Fen::Fen(std::string fen) :
}
if (!IsValid) {
LOG(WARNING)
LOG(warning)
<< "Invalid FEN used in Fen class constructor: " << fen;
} else
InitFenState();
......@@ -358,7 +358,7 @@ void Fen::BuildBoard(Board<PPiece> *board) {
rowID++;
}
} else
LOG(ERROR)
LOG(error)
<< "Can't build board: " << GetErrorMsg();
}
} // namespace model
......
......@@ -17,6 +17,7 @@
#include "Move.hpp"
#include "Coord.hpp"
#include <iostream>
#include "log.hpp"
namespace ochess {
namespace model {
......
......@@ -15,6 +15,7 @@
#endif
// ---------- Boost ----------
#include <cctype> // For tolower()
#include <boost/program_options.hpp>
// ---------- ochess ----------
#include "log.hpp"
#include "gui/mainframe/MainFrame.hpp"
......@@ -23,18 +24,25 @@
#include "command/CommandManager.hpp"
// ---------- Global Variables ----------
namespace ochess {
CommandManager CMD;
ConfigManager CNF;
CommandManager CMD;
ConfigManager CNF;
}
using namespace ochess;
namespace po = boost::program_options;
/**
* Main Application
*/
class OChessApp: public wxApp {
private:
bool TraceEnable;
public:
bool OnInit() override {
OC_INIT_LOG();
TraceEnable = false;
if(!ParseArguments())
return(false);
OC_INIT_LOG(TraceEnable);
ochess::gui::MainFrame *frame = new ochess::gui::MainFrame("OChess",
wxPoint(50, 50), wxSize(450, 340));
......@@ -42,6 +50,33 @@ public:
return true;
}
bool ParseArguments() {
try {
po::options_description desc("OChess options");
desc.add_options()("help", "show help")("trace", "display trace");
//LOG(debug) << argc;
po::variables_map vm;
po::store(
po::parse_command_line(argc, argv.operator char * *(),
desc), vm);
po::notify(vm);
if (vm.count("help")) {
std::cout << desc << "\n";
}
if (vm.count("trace")) {
TraceEnable=true;
}
} catch (exception &e) {
cerr << "error: " << e.what() << "\n";
return(false);
} catch (...) {
cerr << "Exception of unknown type!\n";
return(false);
}
return(true);
}
};
// Create Main base on OChessApp
......
......@@ -4,9 +4,12 @@ namespace ochess
{
namespace pgn
{
PGN::PGN(string file_path) : line(1), done(true)
PGN::PGN(string file_path) : line(1), done(true), game(nullptr), col(1)
{
LOG(debug) << "PGN parser is opening " << file_path;
file.open(file_path);
if(!IsOpen())
LOG(error) << "Failed to open PGN file " << file_path;
}
PGN::~PGN()
......@@ -16,7 +19,7 @@ namespace ochess
void PGN::abort(string reason, short colOffset = 0)
{
cerr << "Error Ln " << line << ",Col " << col + colOffset << ": " << reason << endl;
LOG(error) << "PGN parser error Ln " << line << ",Col " << col + colOffset << ": " << reason;
exit(1);
}
......@@ -49,6 +52,7 @@ namespace ochess
}
void PGN::parseNextGame()
{
LOG(debug) << "PGN parser is parsing the next game (Line "<< line << " Column " << col<<")...";
if (NEXTCHAR() == EOF)
{
done = true;
......@@ -95,9 +99,11 @@ namespace ochess
if (NEXTCHAR() != EOF)
read();
}
LOG(debug) << "Parsing done";
}
void PGN::extractClock(string data, short *clock)
{
LOG(trace) << "Extracting clock from comment";
string values[3];
short curValue = 0;
unsigned long i = 0;
......@@ -291,6 +297,7 @@ namespace ochess
}
void PGN::parseComment(Move *line)
{
LOG(trace) << "Parsing comment";
read(); // Read the {
while (NEXTCHAR() != '}')
{
......
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