+13
src-tauri/src/frontend_calls/load_previous_tabs.rs
+13
src-tauri/src/frontend_calls/load_previous_tabs.rs
···
1
+
use std::collections::HashMap;
2
+
3
+
use tauri::State;
4
+
5
+
use crate::{ structs::nodes::Node, utils::config::Config };
6
+
7
+
#[tauri::command]
8
+
pub fn load_previous_tabs( conf: State<Config> ) -> HashMap<String, Vec<Node>> {
9
+
let config = conf.store.lock().unwrap();
10
+
11
+
let tabs = config.loaded_tabs.clone();
12
+
tabs
13
+
}
+2
-1
src-tauri/src/frontend_calls/mod.rs
+2
-1
src-tauri/src/frontend_calls/mod.rs
+17
-5
src-tauri/src/frontend_calls/sync_tab.rs
+17
-5
src-tauri/src/frontend_calls/sync_tab.rs
···
2
2
3
3
use tauri::State;
4
4
5
-
use crate::{ runtime::commands::RuntimeCommand, structs::nodes::Node };
5
+
use crate::{ runtime::commands::RuntimeCommand, structs::nodes::Node, utils::config::Config };
6
6
7
7
#[tauri::command]
8
-
pub fn sync_tab( graph: Vec<Node>, id: String, cmd: State<Sender<RuntimeCommand>> ){
9
-
cmd.send(RuntimeCommand::AddTab(graph, id)).unwrap();
8
+
pub fn sync_tab( graph: Vec<Node>, id: String, cmd: State<Sender<RuntimeCommand>>, conf: State<Config> ){
9
+
cmd.send(RuntimeCommand::AddTab(graph.clone(), id.clone())).unwrap();
10
+
11
+
let mut config = conf.store.lock().unwrap();
12
+
config.loaded_tabs.insert(id, graph);
13
+
drop(config);
14
+
15
+
conf.save();
10
16
}
11
17
12
18
#[tauri::command]
13
-
pub fn discard_tab( id: String, cmd: State<Sender<RuntimeCommand>> ){
14
-
cmd.send(RuntimeCommand::RemoveTab(id)).unwrap();
19
+
pub fn discard_tab( id: String, cmd: State<Sender<RuntimeCommand>>, conf: State<Config> ){
20
+
cmd.send(RuntimeCommand::RemoveTab(id.clone())).unwrap();
21
+
22
+
let mut config = conf.store.lock().unwrap();
23
+
config.loaded_tabs.remove(&id);
24
+
drop(config);
25
+
26
+
conf.save();
15
27
}
+3
-2
src-tauri/src/lib.rs
+3
-2
src-tauri/src/lib.rs
···
16
16
#[tokio::main]
17
17
pub async fn run() {
18
18
// TODO: Impl background running by default
19
-
// TODO: Auto loading last loaded tabs
19
+
// TODO: Delay close if unsaved tabs
20
20
21
21
let container_folder = dirs::config_dir().unwrap().join("VRCMacros");
22
22
···
47
47
get_addresses::get_addresses,
48
48
save_graph::save_graph,
49
49
sync_tab::sync_tab,
50
-
sync_tab::discard_tab
50
+
sync_tab::discard_tab,
51
+
load_previous_tabs::load_previous_tabs
51
52
])
52
53
.manage(conf)
53
54
.manage(&ADDRESSES)
+2
-2
src-tauri/src/setup.rs
+2
-2
src-tauri/src/setup.rs
···
3
3
4
4
use flate2::read::GzDecoder;
5
5
use serde_json::{ Map, Value };
6
-
use tauri::{ App, Emitter, Listener, Manager };
6
+
use tauri::{ App, Emitter, Listener, Manager, State };
7
7
8
-
use crate::{ osc::{ self, OSCMessage }, runtime::{ commands::RuntimeCommand, nodes::RuntimeNodeTree, runtime, runtime_dry }, structs::parameter_types::ParameterType };
8
+
use crate::{ osc::{ self, OSCMessage }, runtime::{ commands::RuntimeCommand, nodes::RuntimeNodeTree, runtime, runtime_dry }, structs::parameter_types::ParameterType, utils::config::Config };
9
9
10
10
pub fn setup(
11
11
app: &mut App,
+4
-8
src-tauri/src/structs/nodes.rs
+4
-8
src-tauri/src/structs/nodes.rs
···
1
1
use serde::{ Deserialize, Serialize };
2
2
use serde_json::Value;
3
3
4
-
#[derive(Serialize, Deserialize, Debug)]
4
+
#[derive(Serialize, Deserialize, Debug, Clone)]
5
5
pub struct Node{
6
6
pub id: String,
7
7
pub name: String,
···
13
13
pub type_id: String
14
14
}
15
15
16
-
impl Node{
17
-
18
-
}
19
-
20
-
#[derive(Serialize, Deserialize, Debug)]
16
+
#[derive(Serialize, Deserialize, Debug, Clone)]
21
17
pub struct NodeStatic{
22
18
pub name: String,
23
19
···
26
22
pub value: Value
27
23
}
28
24
29
-
#[derive(Serialize, Deserialize, Debug)]
25
+
#[derive(Serialize, Deserialize, Debug, Clone)]
30
26
pub struct NodeOutput{
31
27
pub name: String,
32
28
···
35
31
pub connections: Vec<NodeOutputConnections>
36
32
}
37
33
38
-
#[derive(Serialize, Deserialize, Debug)]
34
+
#[derive(Serialize, Deserialize, Debug, Clone)]
39
35
pub struct NodeOutputConnections{
40
36
pub name: String,
41
37
pub node: String,
+14
-34
src-tauri/src/utils/config.rs
+14
-34
src-tauri/src/utils/config.rs
···
1
-
use std::{
2
-
collections::HashMap,
3
-
fs::File,
4
-
io::{Read, Write},
5
-
path::PathBuf,
6
-
sync::Mutex,
7
-
};
1
+
use std::{ collections::HashMap, fs::File, io::{ Read, Write }, path::PathBuf, sync::Mutex };
8
2
9
-
use flate2::{read::GzDecoder, write::GzEncoder, Compression};
10
-
use serde_json::Value;
3
+
use flate2::{ read::GzDecoder, write::GzEncoder, Compression };
4
+
use serde::{ Deserialize, Serialize };
5
+
6
+
use crate::structs::nodes::Node;
7
+
8
+
#[derive(Clone, Serialize, Deserialize, Debug)]
9
+
pub struct ConfigValues{
10
+
#[serde(default)]
11
+
pub loaded_tabs: HashMap<String, Vec<Node>>
12
+
}
11
13
12
14
pub struct Config {
13
-
store: Mutex<HashMap<String, Value>>,
15
+
pub store: Mutex<ConfigValues>,
14
16
path: PathBuf,
15
17
}
16
18
···
26
28
"{}".into()
27
29
};
28
30
29
-
let json: Value = serde_json::from_str(&json_string).unwrap();
30
-
31
-
let mut hashmap = HashMap::new();
32
-
33
-
let obj = json.as_object().unwrap();
34
-
for (key, val) in obj {
35
-
hashmap.insert(key.clone(), val.clone());
36
-
}
31
+
let json: ConfigValues = serde_json::from_str(&json_string).unwrap();
37
32
38
33
Config {
39
-
store: Mutex::new(hashmap),
34
+
store: Mutex::new(json),
40
35
path: path,
41
-
}
42
-
}
43
-
44
-
pub fn set(&self, key: &str, value: Value) {
45
-
self.store.lock().unwrap().insert(key.to_owned(), value);
46
-
}
47
-
48
-
pub fn get(&self, key: &str) -> Option<Value> {
49
-
let store = self.store.lock().unwrap();
50
-
let val = store.get(&key.to_owned());
51
-
52
-
if val.is_none() {
53
-
None
54
-
} else {
55
-
Some(val.unwrap().clone())
56
36
}
57
37
}
58
38
+20
-6
src/Mangers/NodeManager.tsx
+20
-6
src/Mangers/NodeManager.tsx
···
24
24
NodeManager.Instance = this;
25
25
26
26
listen('load_new_tab', ( ev: any ) => {
27
-
this._loadFromConfig(ev.payload.path, ev.payload.graph);
28
-
})
27
+
this._loadFromConfig(ev.payload.path, null, ev.payload.graph);
28
+
});
29
+
30
+
invoke('load_previous_tabs').then(async ( tabs: any ) => {
31
+
let version = await getVersion();
32
+
33
+
for(let tab of Object.entries(tabs)){
34
+
console.log(tab);
35
+
36
+
await this._loadFromConfig(null, tab[0], JSON.stringify({
37
+
tab_name: 'test',
38
+
version,
39
+
graph: tab[1]
40
+
}));
41
+
};
42
+
});
29
43
}
30
44
31
45
32
46
private _tabUpdateHook: ( tabs: TabHashMap ) => void = () => {};
33
47
private _tabChangeHook: () => void = () => {};
34
48
35
-
public async AddTab( name: string ): Promise<Tab>{
49
+
public async AddTab( name: string, id: string | null = null ): Promise<Tab>{
36
50
let [ selected, setSelected ] = createSignal(false);
37
51
let [ needsSave, setNeedsSave ] = createSignal(false);
38
52
39
53
let tab: Tab = {
40
54
name: name,
41
-
id: await NodeManager.Instance.GetNewNodeId(),
55
+
id: id || await NodeManager.Instance.GetNewNodeId(),
42
56
nodes: [],
43
57
saveLocation: null,
44
58
···
206
220
if(needsSave)tab.setNeedsSave(true);
207
221
}
208
222
209
-
private async _loadFromConfig( path: string, config: string ){
223
+
private async _loadFromConfig( path: string | null, id: string | null, config: string ){
210
224
let json = JSON.parse(config);
211
225
212
226
if(
···
215
229
!json.graph
216
230
)return;
217
231
218
-
let tab = await this.AddTab(json.tab_name);
232
+
let tab = await this.AddTab(json.tab_name, id);
219
233
tab.refuseSync = true;
220
234
tab.saveLocation = path;
221
235