-
Notifications
You must be signed in to change notification settings - Fork 17
Description
It would be nice to have ability to serialize and deserialize storages and pointers with serde. It can be useful in game when you want to save current CGS state. However, it's not easy as I thought before.
Basically, serde isn't a big problem, this test works well after a few lines added:
fn test_serde() {
#[derive(Serialize, Deserialize)]
struct Node {
value: i32,
}
let mut storage = Storage::new();
storage.create(Node { value: 32 });
storage.create(Node { value: 64 });
let pointers: Vec<Pointer<Node>> = storage
.iter_all()
.map(|v| storage.pin(&v))
.collect();
let storage_serialized = serde_json::to_string(&storage).unwrap();
let storage_deserialized: Storage<Node> = serde_json::from_str(&storage_serialized).unwrap();
let pointers_serialized = serde_json::to_string(&pointers).unwrap();
let pointers_deserialized: Vec<Pointer<Node>> = serde_json::from_str(&pointers_serialized).unwrap();
assert_eq!(storage_deserialized.iter_all().count(), 2);
assert_eq!(storage_deserialized.iter().count(), 2);
assert_eq!(storage_deserialized[&pointers_deserialized[0]].value, 32);
}It's definitely safe to deserialize Storage and pointers. But there is one condition - you must not have any Storage in memory before deserializing.
Each Storage has unique identifier, that is used by pointers to link with specific storage. Identifier is controlled by static AtomicUsize. So, deserialized Storage uses "old" identifier, that isn't valid in the new program state. Pointers to deserialised Storage will be able to retrieve data from user's Storage and vise versa.
How to solve this challenge?
My idea is to provide procedural macro for user-defined structs.
Rough code:
#[derive(FroggySerialize)]
struct MyWorld {
storage1: Storage<MyType>,
storage2: Storage<MyAnotherType>,
pointers: Vec<Pointer>,
#[serde(skip)] // ability to use serde's attributes
unnecessary_data: i32,
necessary_user_data: MyAwesomeType,
}This macro will provide custom serde::Serialize and serde::Deserialize traits implementation.
- Serializing
- sync pending
- serialize data (we don't even need
meta, for example)
- Deserializing
- deserialize data
- update all unique ids both in
StorageandPointeraccording to current program state - deserialize pointers and sync pending