Apply strict linting to release builds #75
|
@ -120,7 +120,7 @@ impl CoreApp {
|
|||
app_state.game = Some(GameState {
|
||||
white_player,
|
||||
black_player,
|
||||
..GameState::new()
|
||||
..GameState::default()
|
||||
});
|
||||
let game_state = app_state.game.as_ref().unwrap();
|
||||
CoreResponse::PlayingFieldView(playing_field(game_state))
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::{BoardError, Color, Size};
|
||||
use std::collections::HashSet;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct Board {
|
||||
pub size: Size,
|
||||
pub groups: Vec<Group>,
|
||||
|
@ -14,7 +14,7 @@ impl std::fmt::Display for Board {
|
|||
for c in 0..19 {
|
||||
write!(f, "{:2}", c)?;
|
||||
}
|
||||
writeln!(f, "")?;
|
||||
writeln!(f)?;
|
||||
|
||||
for row in 0..self.size.height {
|
||||
write!(f, " {:2}", row)?;
|
||||
|
@ -25,7 +25,7 @@ impl std::fmt::Display for Board {
|
|||
Some(Color::White) => write!(f, " O")?,
|
||||
}
|
||||
}
|
||||
writeln!(f, "")?;
|
||||
writeln!(f)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -38,16 +38,16 @@ impl PartialEq for Board {
|
|||
}
|
||||
|
||||
for group in self.groups.iter() {
|
||||
if !other.groups.contains(&group) {
|
||||
if !other.groups.contains(group) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for group in other.groups.iter() {
|
||||
if !self.groups.contains(&group) {
|
||||
if !self.groups.contains(group) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,7 +79,7 @@ pub struct Coordinate {
|
|||
|
||||
impl Board {
|
||||
pub fn place_stone(mut self, coordinate: Coordinate, color: Color) -> Result<Self, BoardError> {
|
||||
if let Some(_) = self.stone(&coordinate) {
|
||||
if self.stone(&coordinate).is_some() {
|
||||
return Err(BoardError::InvalidPosition);
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,7 @@ impl Board {
|
|||
acc.union(&set).cloned().collect()
|
||||
});
|
||||
|
||||
friendly_group.insert(coordinate.clone());
|
||||
friendly_group.insert(coordinate);
|
||||
|
||||
self.groups
|
||||
.retain(|g| g.coordinates.is_disjoint(&friendly_group));
|
||||
|
@ -138,7 +138,7 @@ impl Board {
|
|||
let mut grps: Vec<Group> = Vec::new();
|
||||
|
||||
adjacent_spaces.for_each(|coord| match self.group(&coord) {
|
||||
None => return,
|
||||
None => {}
|
||||
Some(adj) => {
|
||||
if group.color == adj.color {
|
||||
return;
|
||||
|
@ -157,15 +157,14 @@ impl Board {
|
|||
group
|
||||
.coordinates
|
||||
.iter()
|
||||
.map(|c| self.adjacencies(c))
|
||||
.flatten()
|
||||
.flat_map(|c| self.adjacencies(c))
|
||||
.collect::<HashSet<Coordinate>>()
|
||||
}
|
||||
|
||||
pub fn liberties(&self, group: &Group) -> usize {
|
||||
self.group_halo(group)
|
||||
.into_iter()
|
||||
.filter(|c| self.stone(&c) == None)
|
||||
.filter(|c| self.stone(c).is_none())
|
||||
.count()
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
use std::{ffi::OsStr, io::Read, os::unix::ffi::OsStrExt, path::PathBuf};
|
||||
use std::{io::Read, path::PathBuf};
|
||||
|
||||
use sgf::{go, parse_sgf, Game};
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum Error {
|
||||
/*
|
||||
#[error("Database permission denied")]
|
||||
PermissionDenied,
|
||||
*/
|
||||
#[error("An IO error occurred: {0}")]
|
||||
IOError(std::io::Error),
|
||||
}
|
||||
|
@ -19,7 +21,6 @@ impl From<std::io::Error> for Error {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct Database {
|
||||
path: PathBuf,
|
||||
games: Vec<go::Game>,
|
||||
}
|
||||
|
||||
|
@ -56,11 +57,7 @@ impl Database {
|
|||
}
|
||||
}
|
||||
|
||||
Ok(Database { path, games })
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.games.len()
|
||||
Ok(Database { games })
|
||||
}
|
||||
|
||||
pub fn all_games(&self) -> impl Iterator<Item = &go::Game> {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#[macro_use]
|
||||
extern crate config_derive;
|
||||
|
||||
mod api;
|
||||
|
@ -10,11 +9,6 @@ pub use api::{
|
|||
mod board;
|
||||
pub use board::*;
|
||||
|
||||
/*
|
||||
mod config;
|
||||
pub use config::*;
|
||||
*/
|
||||
|
||||
mod database;
|
||||
|
||||
mod types;
|
||||
|
|
|
@ -77,20 +77,17 @@ pub struct AppState {
|
|||
impl AppState {
|
||||
pub fn new(database_path: DatabasePath) -> Self {
|
||||
Self {
|
||||
game: Some(GameState::new()),
|
||||
game: Some(GameState::default()),
|
||||
database: Database::open_path(database_path.to_path_buf()).unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn place_stone(&mut self, req: PlayStoneRequest) {
|
||||
match self.game {
|
||||
Some(ref mut game) => {
|
||||
let _ = game.place_stone(Coordinate {
|
||||
column: req.column,
|
||||
row: req.row,
|
||||
});
|
||||
}
|
||||
None => {}
|
||||
if let Some(ref mut game) = self.game {
|
||||
let _ = game.place_stone(Coordinate {
|
||||
column: req.column,
|
||||
row: req.row,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -142,9 +139,9 @@ pub struct GameState {
|
|||
pub black_clock: Duration,
|
||||
}
|
||||
|
||||
impl GameState {
|
||||
pub fn new() -> GameState {
|
||||
GameState {
|
||||
impl Default for GameState {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
board: Board::new(),
|
||||
past_positions: vec![],
|
||||
conversation: vec![],
|
||||
|
@ -161,7 +158,9 @@ impl GameState {
|
|||
black_clock: Duration::from_secs(600),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl GameState {
|
||||
fn place_stone(&mut self, coordinate: Coordinate) -> Result<(), BoardError> {
|
||||
let board = self.board.clone();
|
||||
let new_board = board.place_stone(coordinate, self.current_player)?;
|
||||
|
|
|
@ -76,7 +76,7 @@ impl BoardElement {
|
|||
}
|
||||
|
||||
fn addr(&self, column: u8, row: u8) -> usize {
|
||||
((row as usize) * (self.size.width as usize) + (column as usize)) as usize
|
||||
(row as usize) * (self.size.width as usize) + (column as usize)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,5 +28,5 @@ where
|
|||
let result = f();
|
||||
let end = std::time::Instant::now();
|
||||
println!("[Trace: {}] {:?}", trace_name, end - start);
|
||||
return result;
|
||||
result
|
||||
}
|
||||
|
|
|
@ -34,8 +34,8 @@ fn handle_response(api: CoreApi, app_window: &AppWindow, message: CoreResponse)
|
|||
app_window.set_content(&field);
|
||||
*playing_field = Some(field);
|
||||
})
|
||||
} else {
|
||||
playing_field.as_ref().map(|field| field.update_view(view));
|
||||
} else if let Some(field) = playing_field.as_ref() {
|
||||
field.update_view(view)
|
||||
}
|
||||
}),
|
||||
CoreResponse::UpdatedConfigurationView(view) => perftrace("UpdatedConfiguration", || {
|
||||
|
@ -56,13 +56,13 @@ fn main() {
|
|||
);
|
||||
|
||||
let config_path = std::env::var("CONFIG")
|
||||
.and_then(|config| Ok(std::path::PathBuf::from(config)))
|
||||
.map(std::path::PathBuf::from)
|
||||
.or({
|
||||
std::env::var("HOME").and_then(|base| {
|
||||
std::env::var("HOME").map(|base| {
|
||||
let mut config_path = std::path::PathBuf::from(base);
|
||||
config_path.push(".config");
|
||||
config_path.push("kifu");
|
||||
Ok(config_path)
|
||||
config_path
|
||||
})
|
||||
})
|
||||
.expect("no config path could be found");
|
||||
|
@ -87,7 +87,7 @@ fn main() {
|
|||
let (gtk_tx, gtk_rx) =
|
||||
gtk::glib::MainContext::channel::<CoreResponse>(gtk::glib::PRIORITY_DEFAULT);
|
||||
|
||||
let app_window = AppWindow::new(&app);
|
||||
let app_window = AppWindow::new(app);
|
||||
|
||||
let api = CoreApi {
|
||||
gtk_tx,
|
||||
|
@ -123,5 +123,5 @@ fn main() {
|
|||
println!("running the gtk loop");
|
||||
app.run();
|
||||
|
||||
let _ = runtime.block_on(async { core_handle.await });
|
||||
let _ = runtime.block_on(core_handle);
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ impl ObjectImpl for BoardPrivate {
|
|||
|
||||
match background {
|
||||
Ok(Some(ref background)) => {
|
||||
context.set_source_pixbuf(&background, 0., 0.);
|
||||
context.set_source_pixbuf(background, 0., 0.);
|
||||
context.paint().expect("paint should succeed");
|
||||
}
|
||||
Ok(None) | Err(_) => context.set_source_rgb(0.7, 0.7, 0.7),
|
||||
|
@ -140,11 +140,8 @@ impl ObjectImpl for BoardPrivate {
|
|||
|
||||
(0..19).for_each(|col| {
|
||||
(0..19).for_each(|row| {
|
||||
match board.stone(row, col) {
|
||||
IntersectionElement::Filled(stone) => {
|
||||
pen.stone(&context, row, col, stone.color, stone.liberties);
|
||||
}
|
||||
_ => {}
|
||||
if let IntersectionElement::Filled(stone) = board.stone(row, col) {
|
||||
pen.stone(context, row, col, stone.color, stone.liberties);
|
||||
};
|
||||
})
|
||||
});
|
||||
|
@ -152,15 +149,18 @@ impl ObjectImpl for BoardPrivate {
|
|||
let cursor = cursor_location.borrow();
|
||||
match *cursor {
|
||||
None => {}
|
||||
Some(ref cursor) => match board.stone(cursor.row, cursor.column) {
|
||||
IntersectionElement::Empty(_) => pen.ghost_stone(
|
||||
context,
|
||||
cursor.row,
|
||||
cursor.column,
|
||||
*current_player.borrow(),
|
||||
),
|
||||
_ => {}
|
||||
},
|
||||
Some(ref cursor) => {
|
||||
if let IntersectionElement::Empty(_) =
|
||||
board.stone(cursor.row, cursor.column)
|
||||
{
|
||||
pen.ghost_stone(
|
||||
context,
|
||||
cursor.row,
|
||||
cursor.column,
|
||||
*current_player.borrow(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
let render_end = std::time::Instant::now();
|
||||
println!("board rendering time: {:?}", render_end - render_start);
|
||||
|
@ -208,16 +208,17 @@ impl ObjectImpl for BoardPrivate {
|
|||
let cursor = cursor.borrow();
|
||||
match *cursor {
|
||||
None => {}
|
||||
Some(ref cursor) => match board.stone(cursor.row, cursor.column) {
|
||||
IntersectionElement::Empty(request) => {
|
||||
Some(ref cursor) => {
|
||||
if let IntersectionElement::Empty(request) =
|
||||
board.stone(cursor.row, cursor.column)
|
||||
{
|
||||
println!("need to send request: {:?}", request);
|
||||
api.borrow()
|
||||
.as_ref()
|
||||
.expect("API must exist")
|
||||
.dispatch(request);
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ impl Chat {
|
|||
element.messages.into_iter().for_each(|msg| {
|
||||
s.imp().chat_history.append(
|
||||
>k::Label::builder()
|
||||
.label(&msg)
|
||||
.label(msg)
|
||||
.halign(gtk::Align::Start)
|
||||
.build(),
|
||||
)
|
||||
|
|
|
@ -26,8 +26,8 @@ glib::wrapper! {
|
|||
pub struct GamePreview(ObjectSubclass<GamePreviewPrivate>) @extends gtk::Box, gtk::Widget, @implements gtk::Orientable;
|
||||
}
|
||||
|
||||
impl GamePreview {
|
||||
pub fn new() -> GamePreview {
|
||||
impl Default for GamePreview {
|
||||
fn default() -> Self {
|
||||
let s: Self = Object::builder().build();
|
||||
s.set_orientation(gtk::Orientation::Horizontal);
|
||||
s.set_homogeneous(true);
|
||||
|
@ -41,7 +41,9 @@ impl GamePreview {
|
|||
|
||||
s
|
||||
}
|
||||
}
|
||||
|
||||
impl GamePreview {
|
||||
pub fn set_game(&self, element: GamePreviewElement) {
|
||||
self.imp().black_player.set_text(&element.black_player);
|
||||
self.imp().white_player.set_text(&element.white_player);
|
||||
|
|
|
@ -137,7 +137,7 @@ impl Home {
|
|||
.build();
|
||||
s.append(&new_game_button);
|
||||
|
||||
let library = Library::new();
|
||||
let library = Library::default();
|
||||
let library_view = gtk::ScrolledWindow::builder()
|
||||
.hscrollbar_policy(gtk::PolicyType::Never)
|
||||
.min_content_width(360)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use crate::ui::GamePreview;
|
||||
use adw::{prelude::*, subclass::prelude::*};
|
||||
use glib::Object;
|
||||
use gtk::{glib, prelude::*, subclass::prelude::*};
|
||||
use gtk::glib;
|
||||
use kifu_core::ui::GamePreviewElement;
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
|
@ -92,7 +91,7 @@ impl Default for LibraryPrivate {
|
|||
.set_child(Some(
|
||||
>k::Label::builder()
|
||||
.halign(gtk::Align::Start)
|
||||
.ellipsize(pango::EllipsizeMode::End)
|
||||
.ellipsize(gtk::pango::EllipsizeMode::End)
|
||||
.build(),
|
||||
))
|
||||
});
|
||||
|
@ -100,10 +99,9 @@ impl Default for LibraryPrivate {
|
|||
let list_item = list_item.downcast_ref::<gtk::ListItem>().unwrap();
|
||||
let game = list_item.item().and_downcast::<GameObject>().unwrap();
|
||||
let preview = list_item.child().and_downcast::<gtk::Label>().unwrap();
|
||||
match game.game() {
|
||||
Some(game) => preview.set_text(&bind(game)),
|
||||
None => (),
|
||||
};
|
||||
if let Some(game) = game.game() {
|
||||
preview.set_text(&bind(game))
|
||||
}
|
||||
});
|
||||
factory
|
||||
}
|
||||
|
@ -148,18 +146,20 @@ glib::wrapper! {
|
|||
pub struct Library(ObjectSubclass<LibraryPrivate>) @extends adw::Bin, gtk::Widget;
|
||||
}
|
||||
|
||||
impl Library {
|
||||
pub fn new() -> Self {
|
||||
impl Default for Library {
|
||||
fn default() -> Self {
|
||||
let s: Self = Object::builder().build();
|
||||
|
||||
s.set_child(Some(&s.imp().list_view));
|
||||
s
|
||||
}
|
||||
}
|
||||
|
||||
impl Library {
|
||||
pub fn set_games(&self, games: Vec<GamePreviewElement>) {
|
||||
let games = games
|
||||
.into_iter()
|
||||
.map(|g| GameObject::new(g))
|
||||
.map(GameObject::new)
|
||||
.collect::<Vec<GameObject>>();
|
||||
self.imp().model.extend_from_slice(&games);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use adw::prelude::*;
|
||||
use gio::resources_lookup_data;
|
||||
use glib::IsA;
|
||||
use gtk::{prelude::*, STYLE_PROVIDER_PRIORITY_USER};
|
||||
use gtk::STYLE_PROVIDER_PRIORITY_USER;
|
||||
|
||||
mod chat;
|
||||
pub use chat::Chat;
|
||||
|
|
|
@ -50,11 +50,9 @@ impl PlayingField {
|
|||
let chat = Chat::new(view.chat);
|
||||
|
||||
*s.imp().board.borrow_mut() = Some(Board::new(api));
|
||||
s.imp()
|
||||
.board
|
||||
.borrow()
|
||||
.as_ref()
|
||||
.map(|board| s.attach(board, 1, 1, 1, 2));
|
||||
if let Some(board) = s.imp().board.borrow().as_ref() {
|
||||
s.attach(board, 1, 1, 1, 2)
|
||||
}
|
||||
s.attach(&player_card_black, 2, 1, 1, 1);
|
||||
s.attach(&player_card_white, 3, 1, 1, 1);
|
||||
s.attach(&chat, 2, 2, 2, 1);
|
||||
|
@ -63,20 +61,20 @@ impl PlayingField {
|
|||
*s.imp().player_card_black.borrow_mut() = Some(player_card_black);
|
||||
*s.imp().chat.borrow_mut() = Some(chat);
|
||||
|
||||
s.imp().board.borrow().as_ref().map(|board| {
|
||||
if let Some(board) = s.imp().board.borrow().as_ref() {
|
||||
board.set_board(view.board);
|
||||
board.set_current_player(view.current_player);
|
||||
});
|
||||
};
|
||||
|
||||
s
|
||||
}
|
||||
|
||||
pub fn update_view(&self, view: PlayingFieldView) {
|
||||
perftrace("update_view", || {
|
||||
self.imp().board.borrow().as_ref().map(|board| {
|
||||
if let Some(board) = self.imp().board.borrow().as_ref() {
|
||||
board.set_board(view.board);
|
||||
board.set_current_player(view.current_player);
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue