Skip to content

Commit

Permalink
Load & Save working
Browse files Browse the repository at this point in the history
  • Loading branch information
Spydr06 committed Nov 2, 2022
1 parent 7903bcb commit 97d6f5e
Show file tree
Hide file tree
Showing 11 changed files with 142 additions and 182 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,5 @@ version = "0.4.8"
glib = "0.15.12"
serde_json = "1.0"
serde = {version = "1.0.147", features = ["derive"]}
log = "0.4.0"
env_logger = "0.9.0"
75 changes: 65 additions & 10 deletions src/application/data.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use std::{
collections::HashMap,
io::BufReader,
fs::File,
cmp, path::Path
io::{BufReader, Write},
fs::{File, OpenOptions},
sync::atomic::{AtomicU32, Ordering},
cmp,
};

use gtk::gio::{self, prelude::FileExt};
use crate::{
modules::{
Module,
Expand Down Expand Up @@ -55,9 +56,15 @@ impl Selection {
pub struct ApplicationData {
modules: HashMap<String, Module>,
plots: Vec<Plot>,
id_counter: AtomicU32,

#[serde(skip)]
file: Option<gio::File>,

#[serde(skip)]
current_plot: usize,
file: Option<String>,

#[serde(skip)]
selection: Selection
}

Expand All @@ -76,6 +83,7 @@ impl ApplicationData {
modules: HashMap::new(),
plots: vec![Plot::new()],
current_plot: 0usize,
id_counter: AtomicU32::new(0u32),
file: None,
selection: Selection::None
};
Expand All @@ -84,10 +92,8 @@ impl ApplicationData {
data
}

pub fn build<P>(path: P) -> Result<Self, String>
where P: AsRef<Path>
{
let f = File::open(path);
pub fn build(file: gio::File) -> Result<Self, String> {
let f = File::open(file.path().unwrap());
if let Err(err) = f {
return Err(err.to_string());
}
Expand All @@ -96,11 +102,60 @@ impl ApplicationData {

let result: serde_json::Result<ApplicationData> = serde_json::from_reader(reader);
match result {
Ok(data) => Ok(data),
Ok(mut data) => {
info!("Opened file `{}`", file.path().unwrap().to_str().unwrap());
data.set_file(Some(file));
Ok(data)
},
Err(err) => Err(err.to_string()),
}
}

pub fn save(&self) -> Result<(), String> {
if (&self.file).is_none() {
return Err("save_as is not implemented".to_string());
}

let file = self.file.as_ref().unwrap();

info!("Saving to `{}` ...", file.path().unwrap().to_str().unwrap());
let res = OpenOptions::new().write(true).truncate(true).open(file.path().unwrap());
if let Err(err) = res {
return Err(err.to_string());
}

let mut f = res.unwrap();
let result = serde_json::to_string(self);
match result {
Ok(serialized) => {
let res = f.write(serialized.as_bytes());
match res {
Ok(bytes_written) => {
info!("Wrote {} bytes to `{}` successfully", bytes_written, file.path().unwrap().to_str().unwrap());
Ok(())
}
Err(err) => {
Err(err.to_string())
}
}
},
Err(err) => Err(err.to_string())
}
}

pub fn new_id(&self) -> u32 {
self.id_counter.fetch_add(1u32, Ordering::SeqCst)
}

pub fn file(&self) -> &Option<gio::File> {
&self.file
}

pub fn set_file(&mut self, file: Option<gio::File>) -> &mut Self {
self.file = file;
self
}

pub fn add_module(&mut self, module: Module) -> &mut Self {
self.modules.insert(module.name().clone(), module);
self
Expand Down
16 changes: 15 additions & 1 deletion src/application/template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,28 @@ impl ApplicationImpl for ApplicationTemplate {
crate::die("File path is None");
}

let data = ApplicationData::build(file.path().unwrap());
let data = ApplicationData::build(file.to_owned());
if let Err(err) = data {
crate::die(err.as_str());
}

crate::APPLICATION_DATA.with(|d| d.replace(data.unwrap()));
self.create_window(application);
}

fn shutdown(&self, _application: &Self::Type) {
let res = crate::APPLICATION_DATA.with(|d| {
let data = d.borrow();
match data.file() {
Some(_) => data.save(),
None => Err("save_as is not implemented()".to_string()),
}
});

if let Err(err) = res {
crate::die(err.as_str())
}
}
}
impl GtkApplicationImpl for ApplicationTemplate {}
impl AdwApplicationImpl for ApplicationTemplate {}
Expand Down
22 changes: 15 additions & 7 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ mod modules;
mod renderer;
mod simulator;

#[macro_use]
extern crate log;

use std::cell::RefCell;
use adw::prelude::ApplicationExtManual;
use application::{
Expand All @@ -25,10 +28,10 @@ fn init_new() {
let not_mod = data.get_module(&"Not".to_string()).unwrap();
let xor_mod = data.get_module(&"Xor".to_string()).unwrap();

let mut block1 = Block::new(&and_mod, (10, 10));
let mut block2 = Block::new(&or_mod, (110, 10));
let block3 = Block::new(&not_mod, (210, 10));
let block4 = Block::new(&xor_mod, (310, 10));
let mut block1 = Block::new(&and_mod, (10, 10), data.new_id());
let mut block2 = Block::new(&or_mod, (110, 10), data.new_id());
let block3 = Block::new(&not_mod, (210, 10), data.new_id());
let block4 = Block::new(&xor_mod, (310, 10), data.new_id());
block1.connect_to(0u8, Linkage {block_id: 1u32, port: 1u8});
block2.connect_to(0u8, Linkage {block_id: 2u32, port: 0u8});

Expand All @@ -47,12 +50,17 @@ fn init_new() {
});
}

fn main() -> std::io::Result<()> {
fn main() {
env_logger::init();

info!("Starting up LogicRs...");
//init_new();

let application = Application::new();
std::process::exit(application.run());
}

pub fn die<'a>(reason: &'a str) -> ! {
eprintln!("Fatal error: `{reason}`");
std::process::exit(1)
error!("{reason}");
panic!()
}
8 changes: 4 additions & 4 deletions src/modules/builtin.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use super::Module;

pub fn register(data: &mut crate::application::data::ApplicationData) {
data.add_module(Module::new("And".to_string(), 2, 1));
data.add_module(Module::new("Or".to_string(), 2, 1));
data.add_module(Module::new("Not".to_string(), 1, 1));
data.add_module(Module::new("Xor".to_string(), 2, 1));
data.add_module(Module::new_builtin("And".to_string(), 2, 1));
data.add_module(Module::new_builtin("Or".to_string(), 2, 1));
data.add_module(Module::new_builtin("Not".to_string(), 1, 1));
data.add_module(Module::new_builtin("Xor".to_string(), 2, 1));
}
15 changes: 15 additions & 0 deletions src/modules/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use serde::{Serialize, Deserialize};
#[derive(Default, Debug, Serialize, Deserialize, Clone)]
pub struct Module {
name: String,
builtin: bool,
num_inputs: u8,
num_outputs: u8
}
Expand All @@ -13,11 +14,25 @@ impl Module {
pub fn new(name: String, num_inputs: u8, num_outputs: u8) -> Self {
Self {
name,
builtin: false,
num_inputs,
num_outputs
}
}

pub fn new_builtin(name: String, num_inputs: u8, num_outputs: u8) -> Self {
Self {
name,
builtin: true,
num_inputs,
num_outputs
}
}

pub fn builtin(&self) -> bool {
self.builtin
}

pub fn name(&self) -> &String {
&self.name
}
Expand Down
27 changes: 15 additions & 12 deletions src/simulator/block.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
use std::{
sync::atomic::{AtomicU32, Ordering},
f64,
cmp
};
use std::{f64, cmp};

use crate::{
modules::Module,
Expand All @@ -23,36 +19,43 @@ pub enum Connector {
#[derive(Debug, Serialize, Deserialize)]
pub struct Block {
id: u32,
name: String,

position: (i32, i32),
start_pos: (i32, i32), // starting position of drag movements
size: (i32, i32),

#[serde(skip)]
highlighted: bool,

num_inputs: u8,
num_outputs: u8,
name: String,
connections: Vec<Option<Connection>>
}

impl Block {
pub fn new(module: &&Module, position: (i32, i32)) -> Self {
static ID: AtomicU32 = AtomicU32::new(0u32);

pub fn new(module: &&Module, position: (i32, i32), id: u32) -> Self {
let num_inputs = module.get_num_inputs();
let num_outputs = module.get_num_outputs();
let mut connections = Vec::with_capacity(num_outputs as usize);
for _ in 0..num_outputs {
connections.push(None);
}

let name = module.name().clone();

Self {
id: ID.fetch_add(1u32, Ordering::SeqCst),
id,
position,
start_pos: (0, 0),
size: (75, cmp::max(num_inputs, num_outputs) as i32 * 25 + 50),
size: (
cmp::max(75, (name.len() * 10) as i32),
cmp::max(num_inputs, num_outputs) as i32 * 25 + 50
),
highlighted: false,
num_inputs,
num_outputs,
name: module.name().clone(),
name,
connections,
}
}
Expand Down
14 changes: 8 additions & 6 deletions src/ui/dialogs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use gtk::{
use std::{future::Future, rc::Rc};
use crate::modules::Module;

fn create_new_module(name: String, num_inputs: i32, num_outputs: i32) -> Result<(), String> {
fn create_new_module(name: String, num_inputs: u8, num_outputs: u8) -> Result<(), String> {
if name.is_empty() {
return Err("Invalid name".to_string());
}
Expand All @@ -19,12 +19,14 @@ fn create_new_module(name: String, num_inputs: i32, num_outputs: i32) -> Result<
exists = data.borrow().module_exists(&name);
});
if exists {
return Err(format!("Module with name \"{}\" already exists", name));
let err = format!("Module with name \"{}\" already exists", name);
warn!("{err}");
return Err(err);
}

println!("Create new Module \"{}\"\nwith: {} inputs\n {} outputs", name, num_inputs, num_outputs);
info!("Create new Module \"{}\"\nwith: {} inputs\n {} outputs", name, num_inputs, num_outputs);
crate::APPLICATION_DATA.with(|data| {
data.borrow_mut().add_module(Module::new(name, num_inputs as u8, num_outputs as u8));
data.borrow_mut().add_module(Module::new(name, num_inputs, num_outputs));
});

Ok(())
Expand Down Expand Up @@ -108,15 +110,15 @@ pub async fn new_module<W: IsA<gtk::Window>>(window: Rc<W>) {
let num_outputs = OUTPUTS.iter().position(|&elem| elem == output_chooser.active_id().unwrap()).unwrap_or_default() + 1;

// generate new module
if let Err(err) = create_new_module(name_input.buffer().text().trim().to_string(), num_inputs as i32, num_outputs as i32) {
if let Err(err) = create_new_module(name_input.buffer().text().trim().to_string(), num_inputs as u8, num_outputs as u8) {
gtk::glib::MainContext::default().spawn_local(invalid_module(window, err));
}
}
}

pub fn new<F>(trigger: &Button, window_size: (i32, i32), on_trigger: fn(Rc<gtk::ApplicationWindow>) -> F)
where
F: Future<Output = ()> + 'static,
F: Future<Output = ()> + 'static
{
let dialog_window = Rc::new(
gtk::ApplicationWindow::builder()
Expand Down
2 changes: 1 addition & 1 deletion src/ui/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
mod circuit_panel;
mod circuit_view;
mod dialogs;
pub mod dialogs;
pub mod main_window;
mod module_list;
2 changes: 1 addition & 1 deletion src/ui/module_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ fn new_list_item(module: &Module) -> ListBoxRow {
crate::APPLICATION_DATA.with(|data| {
let mut data = data.borrow_mut();
let module = data.get_module(&name).unwrap();
let block = Block::new(&module, (0, 0));
let block = Block::new(&module, (0, 0), data.new_id());
data.current_plot_mut().add_block(block);
});
});
Expand Down
Loading

0 comments on commit 97d6f5e

Please sign in to comment.