Compare commits

..

No commits in common. "084a558740887bd40bc3ad40c574d7e2ee30a964" and "741f96360651410ad56ad1ab774af20f6610b355" have entirely different histories.

23 changed files with 61 additions and 383 deletions

2
emseries/Cargo.lock generated
View File

@ -71,7 +71,7 @@ dependencies = [
[[package]] [[package]]
name = "emseries" name = "emseries"
version = "0.6.0" version = "0.5.1"
dependencies = [ dependencies = [
"chrono", "chrono",
"chrono-tz", "chrono-tz",

85
go-sgf/Cargo.lock generated
View File

@ -51,7 +51,6 @@ dependencies = [
"iana-time-zone", "iana-time-zone",
"js-sys", "js-sys",
"num-traits", "num-traits",
"serde",
"time", "time",
"wasm-bindgen", "wasm-bindgen",
"winapi", "winapi",
@ -69,9 +68,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"chrono", "chrono",
"nom", "nom",
"serde",
"thiserror", "thiserror",
"typeshare",
] ]
[[package]] [[package]]
@ -97,12 +94,6 @@ dependencies = [
"cc", "cc",
] ]
[[package]]
name = "itoa"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
[[package]] [[package]]
name = "js-sys" name = "js-sys"
version = "0.3.64" version = "0.3.64"
@ -179,54 +170,6 @@ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]]
name = "ryu"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
[[package]]
name = "serde"
version = "1.0.164"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.164"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.18",
]
[[package]]
name = "serde_json"
version = "1.0.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3"
dependencies = [
"itoa",
"ryu",
"serde",
]
[[package]]
name = "syn"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.18" version = "2.0.18"
@ -255,7 +198,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.18", "syn",
] ]
[[package]] [[package]]
@ -269,28 +212,6 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "typeshare"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f44d1a2f454cb35fbe05b218c410792697e76bd868f48d3a418f2cd1a7d527d6"
dependencies = [
"chrono",
"serde",
"serde_json",
"typeshare-annotation",
]
[[package]]
name = "typeshare-annotation"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc670d0e358428857cc3b4bf504c691e572fccaec9542ff09212d3f13d74b7a9"
dependencies = [
"quote",
"syn 1.0.109",
]
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.9" version = "1.0.9"
@ -324,7 +245,7 @@ dependencies = [
"once_cell", "once_cell",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.18", "syn",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@ -346,7 +267,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.18", "syn",
"wasm-bindgen-backend", "wasm-bindgen-backend",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]

View File

@ -6,8 +6,6 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
chrono = { version = "0.4", features = [ "serde" ] }
nom = { version = "7" } nom = { version = "7" }
serde = { version = "1", features = [ "derive" ] }
thiserror = { version = "1"} thiserror = { version = "1"}
typeshare = { version = "1" } chrono = { version = "0.4" }

View File

@ -1,8 +1,6 @@
use chrono::{Datelike, NaiveDate}; use chrono::{Datelike, NaiveDate};
use serde::{Deserialize, Serialize};
use std::num::ParseIntError; use std::num::ParseIntError;
use thiserror::Error; use thiserror::Error;
use typeshare::typeshare;
#[derive(Debug, Error, PartialEq)] #[derive(Debug, Error, PartialEq)]
pub enum Error { pub enum Error {
@ -16,8 +14,7 @@ pub enum Error {
Unsupported, Unsupported,
} }
#[derive(Clone, Debug, PartialEq, PartialOrd, Deserialize, Serialize)] #[derive(Clone, Debug, PartialEq, PartialOrd)]
#[typeshare]
pub enum Date { pub enum Date {
Year(i32), Year(i32),
YearMonth(i32, u32), YearMonth(i32, u32),

View File

@ -72,8 +72,6 @@ use crate::{
date::{self, parse_date_field, Date}, date::{self, parse_date_field, Date},
tree::{parse_collection, ParseSizeError, Size}, tree::{parse_collection, ParseSizeError, Size},
}; };
use serde::{Deserialize, Serialize};
use typeshare::typeshare;
#[derive(Debug)] #[derive(Debug)]
pub enum Error<'a> { pub enum Error<'a> {
@ -99,8 +97,7 @@ impl<'a> From<ParseSizeError> for Error<'a> {
} }
} }
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] #[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[typeshare]
pub enum Rank { pub enum Rank {
Kyu(u8), Kyu(u8),
Dan(u8), Dan(u8),
@ -121,12 +118,6 @@ impl TryFrom<&str> for Rank {
} }
} }
impl ToString for Rank {
fn to_string(&self) -> String {
unimplemented!()
}
}
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct GameTree { pub struct GameTree {
pub file_format: i8, pub file_format: i8,

View File

@ -1,10 +1,6 @@
mod date; pub mod date;
pub use date::Date; pub mod go;
pub mod tree;
mod go;
pub use go::{parse_sgf, GameTree, GameType, Rank};
mod tree;
use thiserror::Error; use thiserror::Error;

3
kifu/core/Cargo.lock generated
View File

@ -45,7 +45,6 @@ dependencies = [
"js-sys", "js-sys",
"num-integer", "num-integer",
"num-traits", "num-traits",
"serde",
"time", "time",
"wasm-bindgen", "wasm-bindgen",
"winapi", "winapi",
@ -126,9 +125,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"chrono", "chrono",
"nom", "nom",
"serde",
"thiserror", "thiserror",
"typeshare",
] ]
[[package]] [[package]]

View File

@ -1,7 +1,7 @@
use crate::{ use crate::{
types::{AppState, GameState, Player, Rank}, types::{AppState, GameState, Player, Rank},
ui::{home, playing_field, HomeView, PlayingFieldView}, ui::{new_game, playing_field, NewGameView, PlayingFieldView},
Config, DatabasePath, Config,
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
@ -12,7 +12,8 @@ use typeshare::typeshare;
#[serde(tag = "type", content = "content")] #[serde(tag = "type", content = "content")]
pub enum CoreRequest { pub enum CoreRequest {
CreateGame(CreateGameRequest), CreateGame(CreateGameRequest),
Home, LaunchScreen,
NewGame,
PlayingField, PlayingField,
PlayStone(PlayStoneRequest), PlayStone(PlayStoneRequest),
StartGame, StartGame,
@ -58,7 +59,7 @@ impl From<HotseatPlayerRequest> for Player {
#[typeshare] #[typeshare]
#[serde(tag = "type", content = "content")] #[serde(tag = "type", content = "content")]
pub enum CoreResponse { pub enum CoreResponse {
HomeView(HomeView), NewGameView(NewGameView),
PlayingFieldView(PlayingFieldView), PlayingFieldView(PlayingFieldView),
} }
@ -70,14 +71,8 @@ pub struct CoreApp {
impl CoreApp { impl CoreApp {
pub fn new(config_path: std::path::PathBuf) -> Self { pub fn new(config_path: std::path::PathBuf) -> Self {
println!("config_path: {:?}", config_path);
let config = Config::from_path(config_path).expect("configuration to open"); let config = Config::from_path(config_path).expect("configuration to open");
let state = Arc::new(RwLock::new(AppState::new()));
let db_path: DatabasePath = config.get();
let state = Arc::new(RwLock::new(AppState::new(db_path)));
println!("config: {:?}", config);
println!("games database: {:?}", state.read().unwrap().database.len());
Self { config, state } Self { config, state }
} }
@ -118,9 +113,8 @@ impl CoreApp {
let game_state = app_state.game.as_ref().unwrap(); let game_state = app_state.game.as_ref().unwrap();
CoreResponse::PlayingFieldView(playing_field(game_state)) CoreResponse::PlayingFieldView(playing_field(game_state))
} }
CoreRequest::Home => { CoreRequest::LaunchScreen => CoreResponse::NewGameView(new_game()),
CoreResponse::HomeView(home(self.state.read().unwrap().database.all_games())) CoreRequest::NewGame => CoreResponse::NewGameView(new_game()),
}
CoreRequest::PlayingField => { CoreRequest::PlayingField => {
let app_state = self.state.read().unwrap(); let app_state = self.state.read().unwrap();
let game = app_state.game.as_ref().unwrap(); let game = app_state.game.as_ref().unwrap();

View File

@ -36,7 +36,6 @@ enum OptionNames {
} }
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(untagged)]
pub enum ConfigOption { pub enum ConfigOption {
DatabasePath(DatabasePath), DatabasePath(DatabasePath),
Me(Me), Me(Me),
@ -97,14 +96,14 @@ impl Config {
} }
} }
pub fn set(&mut self, val: ConfigOption) { fn set(&mut self, val: ConfigOption) {
let _ = match val { let _ = match val {
ConfigOption::DatabasePath(_) => self.values.insert(OptionNames::DatabasePath, val), ConfigOption::DatabasePath(_) => self.values.insert(OptionNames::DatabasePath, val),
ConfigOption::Me(_) => self.values.insert(OptionNames::Me, val), ConfigOption::Me(_) => self.values.insert(OptionNames::Me, val),
}; };
} }
pub fn get<'a, T>(&'a self) -> T fn get<'a, T>(&'a self) -> T
where where
T: From<&'a Self>, T: From<&'a Self>,
{ {
@ -112,16 +111,9 @@ impl Config {
} }
} }
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct DatabasePath(PathBuf); pub struct DatabasePath(PathBuf);
impl std::ops::Deref for DatabasePath {
type Target = PathBuf;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl From<&Config> for DatabasePath { impl From<&Config> for DatabasePath {
fn from(config: &Config) -> Self { fn from(config: &Config) -> Self {
match config.values.get(&OptionNames::DatabasePath) { match config.values.get(&OptionNames::DatabasePath) {
@ -131,7 +123,7 @@ impl From<&Config> for DatabasePath {
} }
} }
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Me(Player); pub struct Me(Player);
impl From<&Config> for Option<Me> { impl From<&Config> for Option<Me> {
@ -145,54 +137,3 @@ impl From<&Config> for Option<Me> {
}) })
} }
} }
impl std::ops::Deref for Me {
type Target = Player;
fn deref(&self) -> &Self::Target {
&self.0
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::types::Rank;
use cool_asserts::assert_matches;
#[test]
fn it_can_set_and_get_options() {
let mut config = Config::new(PathBuf::from("."));
config.set(ConfigOption::DatabasePath(DatabasePath(PathBuf::from(
"fixtures/five_games",
))));
config.set(ConfigOption::Me(Me(Player {
name: "Savanni".to_owned(),
rank: Some(Rank::Kyu(10)),
})));
}
#[test]
fn it_can_serialize_and_deserialize() {
let mut config = Config::new(PathBuf::from("."));
config.set(ConfigOption::DatabasePath(DatabasePath(PathBuf::from(
"fixtures/five_games",
))));
config.set(ConfigOption::Me(Me(Player {
name: "Savanni".to_owned(),
rank: Some(Rank::Kyu(10)),
})));
let s = serde_json::to_string(&config.values).unwrap();
println!("{}", s);
let values: HashMap<OptionNames, ConfigOption> = serde_json::from_str(s.as_ref()).unwrap();
println!("options: {:?}", values);
assert_matches!(values.get(&OptionNames::DatabasePath),
Some(ConfigOption::DatabasePath(db_path)) =>
assert_eq!(*db_path, config.get())
);
assert_matches!(values.get(&OptionNames::Me), Some(ConfigOption::Me(val)) =>
assert_eq!(Some(val.clone()), config.get())
);
}
}

View File

@ -1,6 +1,6 @@
use std::{ffi::OsStr, io::Read, os::unix::ffi::OsStrExt, path::PathBuf}; use std::{ffi::OsStr, io::Read, os::unix::ffi::OsStrExt, path::PathBuf};
use go_sgf::{parse_sgf, GameTree}; use go_sgf::go::{parse_sgf, GameTree, GameType};
use thiserror::Error; use thiserror::Error;
#[derive(Error, Debug)] #[derive(Error, Debug)]
@ -17,7 +17,6 @@ impl From<std::io::Error> for Error {
} }
} }
#[derive(Debug)]
pub struct Database { pub struct Database {
path: PathBuf, path: PathBuf,
games: Vec<GameTree>, games: Vec<GameTree>,
@ -50,10 +49,6 @@ impl Database {
Ok(Database { path, games }) Ok(Database { path, games })
} }
pub fn len(&self) -> usize {
self.games.len()
}
pub fn all_games(&self) -> impl Iterator<Item = &GameTree> { pub fn all_games(&self) -> impl Iterator<Item = &GameTree> {
self.games.iter() self.games.iter()
} }
@ -63,7 +58,6 @@ impl Database {
mod test { mod test {
use super::*; use super::*;
use cool_asserts::assert_matches; use cool_asserts::assert_matches;
use go_sgf::{Date, GameType};
#[test] #[test]
fn it_reads_empty_database() { fn it_reads_empty_database() {
@ -85,7 +79,7 @@ mod test {
Some(game) => { Some(game) => {
assert_eq!(game.info.black_player, Some("Steve".to_owned())); assert_eq!(game.info.black_player, Some("Steve".to_owned()));
assert_eq!(game.info.white_player, Some("Savanni".to_owned())); assert_eq!(game.info.white_player, Some("Savanni".to_owned()));
assert_eq!(game.info.date, vec![Date::Date(chrono::NaiveDate::from_ymd_opt(2023, 4, 19).unwrap())]); assert_eq!(game.info.date, vec![chrono::NaiveDate::from_ymd_opt(2023, 4, 19).unwrap()]);
assert_eq!(game.info.komi, Some(6.5)); assert_eq!(game.info.komi, Some(6.5));
} }
); );

View File

@ -13,5 +13,4 @@ mod database;
mod types; mod types;
pub use types::{BoardError, Color, Rank, Size}; pub use types::{BoardError, Color, Rank, Size};
pub mod ui; pub mod ui;

View File

@ -1,11 +1,9 @@
use crate::{ use crate::{
api::PlayStoneRequest, api::PlayStoneRequest,
board::{Board, Coordinate}, board::{Board, Coordinate},
config::DatabasePath,
database::Database,
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::{path::PathBuf, time::Duration}; use std::time::Duration;
use thiserror::Error; use thiserror::Error;
use typeshare::typeshare; use typeshare::typeshare;
@ -45,14 +43,12 @@ impl Default for Size {
#[derive(Debug)] #[derive(Debug)]
pub struct AppState { pub struct AppState {
pub game: Option<GameState>, pub game: Option<GameState>,
pub database: Database,
} }
impl AppState { impl AppState {
pub fn new(database_path: DatabasePath) -> Self { pub fn new() -> Self {
Self { Self {
game: Some(GameState::new()), game: Some(GameState::new()),
database: Database::open_path(database_path.to_path_buf()).unwrap(),
} }
} }
@ -95,7 +91,7 @@ impl From<Rank> for String {
} }
} }
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Player { pub struct Player {
pub name: String, pub name: String,
pub rank: Option<Rank>, pub rank: Option<Rank>,

View File

@ -1,33 +0,0 @@
use go_sgf::{Date, GameTree, Rank};
use serde::{Deserialize, Serialize};
use typeshare::typeshare;
#[derive(Clone, Debug, Deserialize, Serialize)]
#[typeshare]
pub struct GamePreviewElement {
pub date: Vec<Date>,
pub black_player: String,
pub black_rank: Option<Rank>,
pub white_player: String,
pub white_rank: Option<Rank>,
}
impl GamePreviewElement {
pub fn new(game: &GameTree) -> GamePreviewElement {
GamePreviewElement {
date: game.info.date.clone(),
black_player: game
.info
.black_player
.clone()
.unwrap_or("black_player".to_owned()),
black_rank: game.info.black_rank.clone(),
white_player: game
.info
.white_player
.clone()
.unwrap_or("white_player".to_owned()),
white_rank: game.info.white_rank.clone(),
}
}
}

View File

@ -1,3 +1,2 @@
pub mod action; pub mod action;
pub mod game_preview;
pub mod menu; pub mod menu;

View File

@ -1,5 +1,5 @@
mod elements; mod elements;
pub use elements::{action::Action, game_preview::GamePreviewElement, menu::Menu}; pub use elements::{action::Action, menu::Menu};
mod playing_field; mod playing_field;
pub use playing_field::{playing_field, PlayingFieldView}; pub use playing_field::{playing_field, PlayingFieldView};
@ -7,8 +7,8 @@ pub use playing_field::{playing_field, PlayingFieldView};
// mod launch_screen; // mod launch_screen;
// pub use launch_screen::{launch_screen, LaunchScreenView}; // pub use launch_screen::{launch_screen, LaunchScreenView};
mod home; mod new_game;
pub use home::{home, HomeView, HotseatPlayerElement, PlayerElement}; pub use new_game::{new_game, HotseatPlayerElement, NewGameView, PlayerElement};
mod types; mod types;
pub use types::{ pub use types::{

View File

@ -1,5 +1,4 @@
use crate::ui::{Action, GamePreviewElement}; use crate::ui::Action;
use go_sgf::GameTree;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use typeshare::typeshare; use typeshare::typeshare;
@ -49,14 +48,13 @@ pub struct BotPlayerElement {}
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
#[typeshare] #[typeshare]
pub struct HomeView { pub struct NewGameView {
pub black_player: PlayerElement, pub black_player: PlayerElement,
pub white_player: PlayerElement, pub white_player: PlayerElement,
pub games: Vec<GamePreviewElement>,
pub start_game: Action<()>, pub start_game: Action<()>,
} }
pub fn home<'a>(games: impl Iterator<Item = &'a GameTree>) -> HomeView { pub fn new_game() -> NewGameView {
let black_player = PlayerElement::Hotseat(HotseatPlayerElement { let black_player = PlayerElement::Hotseat(HotseatPlayerElement {
placeholder: Some("black player".to_owned()), placeholder: Some("black player".to_owned()),
default_rank: None, default_rank: None,
@ -67,10 +65,9 @@ pub fn home<'a>(games: impl Iterator<Item = &'a GameTree>) -> HomeView {
default_rank: None, default_rank: None,
ranks: rank_strings(), ranks: rank_strings(),
}); });
HomeView { NewGameView {
black_player, black_player,
white_player, white_player,
games: games.map(GamePreviewElement::new).collect(),
start_game: Action { start_game: Action {
id: "start-game-action".to_owned(), id: "start-game-action".to_owned(),
label: "New Game".to_owned(), label: "New Game".to_owned(),

52
kifu/gtk/Cargo.lock generated
View File

@ -121,8 +121,6 @@ dependencies = [
"js-sys", "js-sys",
"num-integer", "num-integer",
"num-traits", "num-traits",
"serde",
"time",
"wasm-bindgen", "wasm-bindgen",
"winapi", "winapi",
] ]
@ -444,7 +442,7 @@ dependencies = [
"cfg-if", "cfg-if",
"js-sys", "js-sys",
"libc", "libc",
"wasi 0.11.0+wasi-snapshot-preview1", "wasi",
"wasm-bindgen", "wasm-bindgen",
] ]
@ -545,17 +543,6 @@ dependencies = [
"system-deps", "system-deps",
] ]
[[package]]
name = "go-sgf"
version = "0.1.0"
dependencies = [
"chrono",
"nom",
"serde",
"thiserror",
"typeshare",
]
[[package]] [[package]]
name = "gobject-sys" name = "gobject-sys"
version = "0.17.4" version = "0.17.4"
@ -798,8 +785,6 @@ dependencies = [
name = "kifu-core" name = "kifu-core"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"chrono",
"go-sgf",
"grid", "grid",
"serde", "serde",
"serde_json", "serde_json",
@ -877,12 +862,6 @@ dependencies = [
"autocfg", "autocfg",
] ]
[[package]]
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]] [[package]]
name = "miniz_oxide" name = "miniz_oxide"
version = "0.6.2" version = "0.6.2"
@ -900,7 +879,7 @@ checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9"
dependencies = [ dependencies = [
"libc", "libc",
"log", "log",
"wasi 0.11.0+wasi-snapshot-preview1", "wasi",
"windows-sys", "windows-sys",
] ]
@ -919,16 +898,6 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c" checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c"
[[package]]
name = "nom"
version = "7.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
dependencies = [
"memchr",
"minimal-lexical",
]
[[package]] [[package]]
name = "num-integer" name = "num-integer"
version = "0.1.45" version = "0.1.45"
@ -1361,17 +1330,6 @@ dependencies = [
"weezl", "weezl",
] ]
[[package]]
name = "time"
version = "0.1.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
dependencies = [
"libc",
"wasi 0.10.0+wasi-snapshot-preview1",
"winapi",
]
[[package]] [[package]]
name = "tokio" name = "tokio"
version = "1.26.0" version = "1.26.0"
@ -1475,12 +1433,6 @@ version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "wasi"
version = "0.10.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
[[package]] [[package]]
name = "wasi" name = "wasi"
version = "0.11.0+wasi-snapshot-preview1" version = "0.11.0+wasi-snapshot-preview1"

View File

@ -2,7 +2,6 @@ release:
cargo build --release cargo build --release
dev: dev:
export CONFIG=.
cargo watch -x 'run --bin kifu-gtk' cargo watch -x 'run --bin kifu-gtk'
screenplay: screenplay:

View File

@ -1 +0,0 @@
{"Me":{"name":"Savanni","rank":{"Kyu":10}},"DatabasePath":"../core/fixtures/five_games"}

View File

@ -2,7 +2,7 @@ use gtk::prelude::*;
use kifu_core::{CoreApp, CoreRequest, CoreResponse}; use kifu_core::{CoreApp, CoreRequest, CoreResponse};
use kifu_gtk::{ use kifu_gtk::{
perftrace, perftrace,
ui::{Home, PlayingField}, ui::{NewGame, PlayingField},
CoreApi, CoreApi,
}; };
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
@ -10,10 +10,10 @@ use std::sync::{Arc, RwLock};
fn handle_response(api: CoreApi, window: gtk::ApplicationWindow, message: CoreResponse) { fn handle_response(api: CoreApi, window: gtk::ApplicationWindow, message: CoreResponse) {
let playing_field = Arc::new(RwLock::new(None)); let playing_field = Arc::new(RwLock::new(None));
match message { match message {
CoreResponse::HomeView(view) => perftrace("HomeView", || { CoreResponse::NewGameView(view) => perftrace("NewGameView", || {
let api = api.clone(); let api = api.clone();
let new_game = Home::new(api, view); let new_game = NewGame::new(api, view);
window.set_child(Some(&new_game)); window.set_child(Some(&new_game));
}), }),
CoreResponse::PlayingFieldView(view) => perftrace("PlayingFieldView", || { CoreResponse::PlayingFieldView(view) => perftrace("PlayingFieldView", || {
@ -44,17 +44,10 @@ fn main() {
.unwrap(), .unwrap(),
); );
let config_path = std::env::var("CONFIG") let user_home = std::env::var("HOME").expect("the user's home directory isn't set");
.and_then(|config| Ok(std::path::PathBuf::from(config))) let mut config_path = std::path::PathBuf::from(user_home);
.or({
std::env::var("HOME").and_then(|base| {
let mut config_path = std::path::PathBuf::from(base);
config_path.push(".config"); config_path.push(".config");
config_path.push("kifu"); config_path.push("kifu");
Ok(config_path)
})
})
.expect("no config path could be found");
let core = CoreApp::new(config_path); let core = CoreApp::new(config_path);
@ -94,7 +87,7 @@ fn main() {
} }
}); });
api.dispatch(CoreRequest::Home); api.dispatch(CoreRequest::NewGame);
} }
}); });

View File

@ -1,42 +0,0 @@
use glib::Object;
use gtk::{glib, prelude::*, subclass::prelude::*};
use kifu_core::ui::GamePreviewElement;
#[derive(Default)]
pub struct GamePreviewPrivate;
#[glib::object_subclass]
impl ObjectSubclass for GamePreviewPrivate {
const NAME: &'static str = "GamePreview";
type Type = GamePreview;
type ParentType = gtk::Box;
}
impl ObjectImpl for GamePreviewPrivate {}
impl WidgetImpl for GamePreviewPrivate {}
impl BoxImpl for GamePreviewPrivate {}
glib::wrapper! {
pub struct GamePreview(ObjectSubclass<GamePreviewPrivate>) @extends gtk::Box, gtk::Widget, @implements gtk::Orientable;
}
impl GamePreview {
pub fn new(element: GamePreviewElement) -> GamePreview {
let s: Self = Object::builder().build();
s.set_orientation(gtk::Orientation::Horizontal);
println!("game_preview: {:?}", element);
let black_player = match element.black_rank {
Some(rank) => format!("{} ({})", element.black_player, rank.to_string()),
None => element.black_player,
};
let white_player = match element.white_rank {
Some(rank) => format!("{} ({})", element.white_player, rank.to_string()),
None => element.white_player,
};
s.append(&gtk::Label::new(Some(&black_player)));
s.append(&gtk::Label::new(Some(&white_player)));
s
}
}

View File

@ -1,17 +1,14 @@
mod chat;
pub use chat::Chat;
mod game_preview;
pub use game_preview::GamePreview;
mod player_card; mod player_card;
pub use player_card::PlayerCard; pub use player_card::PlayerCard;
mod chat;
pub use chat::Chat;
mod playing_field; mod playing_field;
pub use playing_field::PlayingField; pub use playing_field::PlayingField;
mod home; mod new_game;
pub use home::Home; pub use new_game::NewGame;
mod board; mod board;
pub use board::Board; pub use board::Board;

View File

@ -1,9 +1,8 @@
use crate::ui::GamePreview;
use crate::CoreApi; use crate::CoreApi;
use glib::Object; use glib::Object;
use gtk::{glib, prelude::*, subclass::prelude::*}; use gtk::{glib, prelude::*, subclass::prelude::*};
use kifu_core::{ use kifu_core::{
ui::{HomeView, PlayerElement}, ui::{NewGameView, PlayerElement},
CoreRequest, CreateGameRequest, HotseatPlayerRequest, PlayerInfoRequest, CoreRequest, CreateGameRequest, HotseatPlayerRequest, PlayerInfoRequest,
}; };
use std::{cell::RefCell, rc::Rc}; use std::{cell::RefCell, rc::Rc};
@ -83,12 +82,12 @@ impl PlayerDataEntry {
} }
} }
pub struct HomePrivate { pub struct NewGamePrivate {
black_player: Rc<RefCell<Option<PlayerDataEntry>>>, black_player: Rc<RefCell<Option<PlayerDataEntry>>>,
white_player: Rc<RefCell<Option<PlayerDataEntry>>>, white_player: Rc<RefCell<Option<PlayerDataEntry>>>,
} }
impl Default for HomePrivate { impl Default for NewGamePrivate {
fn default() -> Self { fn default() -> Self {
Self { Self {
black_player: Rc::new(RefCell::new(None)), black_player: Rc::new(RefCell::new(None)),
@ -98,22 +97,22 @@ impl Default for HomePrivate {
} }
#[glib::object_subclass] #[glib::object_subclass]
impl ObjectSubclass for HomePrivate { impl ObjectSubclass for NewGamePrivate {
const NAME: &'static str = "Home"; const NAME: &'static str = "NewGame";
type Type = Home; type Type = NewGame;
type ParentType = gtk::Grid; type ParentType = gtk::Grid;
} }
impl ObjectImpl for HomePrivate {} impl ObjectImpl for NewGamePrivate {}
impl WidgetImpl for HomePrivate {} impl WidgetImpl for NewGamePrivate {}
impl GridImpl for HomePrivate {} impl GridImpl for NewGamePrivate {}
glib::wrapper! { glib::wrapper! {
pub struct Home(ObjectSubclass<HomePrivate>) @extends gtk::Grid, gtk::Widget; pub struct NewGame(ObjectSubclass<NewGamePrivate>) @extends gtk::Grid, gtk::Widget;
} }
impl Home { impl NewGame {
pub fn new(api: CoreApi, view: HomeView) -> Home { pub fn new(api: CoreApi, view: NewGameView) -> NewGame {
let s: Self = Object::builder().build(); let s: Self = Object::builder().build();
let black_player = PlayerDataEntry::new(view.black_player); let black_player = PlayerDataEntry::new(view.black_player);
@ -139,12 +138,6 @@ impl Home {
} }
}); });
let game_list = gtk::Box::new(gtk::Orientation::Vertical, 0);
s.attach(&game_list, 1, 3, 2, 1);
view.games
.iter()
.for_each(|game_preview| game_list.append(&GamePreview::new(game_preview.clone())));
s s
} }
} }