/* Copyright 2024, Savanni D'Gerinel This file is part of On the Grid. On the Grid is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. On the Grid is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with On the Grid. If not, see . */ // I have an old Board class which I'm going to update. I'll just copy over the rendering code, but // at the same time I am going to work pretty heavily on the API. // // For a game review, the board needs to interact very well with a game record. So I have to keep // in mind all of that as I work on the API. // // Also, this is going to be a cross-platform application. Today it is Gnome + Rust, but as I // progress I will also need a Progressive Web App so that I can run this on my tablet. Especially // useful if I'm out socializing and happen to be talking to somebody who would enjoy a relaxing // game. Anyway, that is going to impact some of my API decisions. // // First, though, I need to rename my game record. // // Now, let's get the existing code compiling again. // // Okay, that wasn't so bad. I'm a little confused that I don't have a code action for renaming a // symbol, but I'll fix that some other time. Anyway, now let's focus on the goban. // Now, we know what kind of object we have for the current board representation. Let's make use of // that. use glib::Object; use gtk::{prelude::*, subclass::prelude::*}; use std::{rc::Rc, cell::RefCell}; // Internal representation of the Goban drawing area. #[derive(Default)] pub struct GobanPrivate { board_state: Rc>, } #[glib::object_subclass] impl ObjectSubclass for GobanPrivate { const NAME: &'static str = "Goban"; type Type = Goban; type ParentType = gtk::DrawingArea; } impl ObjectImpl for GobanPrivate {} impl WidgetImpl for GobanPrivate {} impl DrawingAreaImpl for GobanPrivate {} /// This Goban, being in the `components` crate, is merely the rendering of a board. This is not /// the primary representation of the board. /// /// In a game of Go, there are certain rules about what are valid moves and what are not. /// Internally, I want to keep track of those, and doing so requires a few things. /// /// - We can never repeat a game state (though I think maybe that is allowed in a few rulesets, but /// I'm coding to the AGA ruleset) /// - We can never play a suicidal move /// /// Finally, updating the board state is non-GUI logic. So, sorry, might be dropping away from GUI /// code for a while to work on the backend representation, some of which already exists. glib::wrapper! { pub struct Goban(ObjectSubclass) @extends gtk::Widget, gtk::DrawingArea; } impl Goban { pub fn new(board_state: otg_core::Goban) -> Self { let s: Self = Object::new(); *s.imp().board_state.borrow_mut() = board_state; s } }