mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Added rtsim crate, added initial persistence model
This commit is contained in:
parent
1ea69156da
commit
ca80d831ce
9
Cargo.lock
generated
9
Cargo.lock
generated
@ -6884,6 +6884,15 @@ dependencies = [
|
|||||||
"veloren-plugin-derive",
|
"veloren-plugin-derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "veloren-rtsim"
|
||||||
|
version = "0.10.0"
|
||||||
|
dependencies = [
|
||||||
|
"ron 0.7.0",
|
||||||
|
"serde",
|
||||||
|
"veloren-common",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "veloren-server"
|
name = "veloren-server"
|
||||||
version = "0.14.0"
|
version = "0.14.0"
|
||||||
|
@ -16,6 +16,7 @@ members = [
|
|||||||
"plugin/api",
|
"plugin/api",
|
||||||
"plugin/derive",
|
"plugin/derive",
|
||||||
"plugin/rt",
|
"plugin/rt",
|
||||||
|
"rtsim",
|
||||||
"server",
|
"server",
|
||||||
"server/agent",
|
"server/agent",
|
||||||
"server-cli",
|
"server-cli",
|
||||||
|
9
rtsim/Cargo.toml
Normal file
9
rtsim/Cargo.toml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
[package]
|
||||||
|
name = "veloren-rtsim"
|
||||||
|
version = "0.10.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
common = { package = "veloren-common", path = "../common" }
|
||||||
|
ron = "0.7"
|
||||||
|
serde = { version = "1.0.110", features = ["derive"] }
|
54
rtsim/src/data/helper.rs
Normal file
54
rtsim/src/data/helper.rs
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
use serde::{
|
||||||
|
de::{DeserializeOwned, Error},
|
||||||
|
Deserialize, Deserializer, Serialize, Serializer,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct V<T>(pub T);
|
||||||
|
|
||||||
|
impl<T: Serialize> Serialize for V<T> {
|
||||||
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||||
|
self.0.serialize(serializer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de, T: Version> Deserialize<'de> for V<T> {
|
||||||
|
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
|
||||||
|
T::try_from_value_compat(ron::Value::deserialize(deserializer)?)
|
||||||
|
.map(Self)
|
||||||
|
.map_err(|e| D::Error::custom(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<U, T: Latest<U>> Latest<U> for V<T> {
|
||||||
|
fn to_unversioned(self) -> U { self.0.to_unversioned() }
|
||||||
|
|
||||||
|
fn from_unversioned(x: U) -> Self { Self(T::from_unversioned(x)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Latest<T> {
|
||||||
|
fn to_unversioned(self) -> T;
|
||||||
|
fn from_unversioned(x: T) -> Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Version: Sized + DeserializeOwned {
|
||||||
|
type Prev: Version;
|
||||||
|
|
||||||
|
fn migrate(prev: Self::Prev) -> Self;
|
||||||
|
|
||||||
|
fn try_from_value_compat(value: ron::Value) -> Result<Self, ron::Error> {
|
||||||
|
value.clone().into_rust().or_else(|e| {
|
||||||
|
Ok(Self::migrate(
|
||||||
|
<Self as Version>::Prev::try_from_value_compat(value).map_err(|_| e)?,
|
||||||
|
))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub enum Bottom {}
|
||||||
|
|
||||||
|
impl Version for Bottom {
|
||||||
|
type Prev = Self;
|
||||||
|
|
||||||
|
fn migrate(prev: Self::Prev) -> Self { prev }
|
||||||
|
}
|
10
rtsim/src/data/mod.rs
Normal file
10
rtsim/src/data/mod.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
pub mod helper;
|
||||||
|
pub mod version;
|
||||||
|
|
||||||
|
pub mod world;
|
||||||
|
|
||||||
|
pub use self::world::World;
|
||||||
|
|
||||||
|
pub struct Data {
|
||||||
|
world: World,
|
||||||
|
}
|
72
rtsim/src/data/version/mod.rs
Normal file
72
rtsim/src/data/version/mod.rs
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
// # Hey, you! Yes, you!
|
||||||
|
//
|
||||||
|
// Don't touch anything in this module, or any sub-modules. No, really. Bad
|
||||||
|
// stuff will happen.
|
||||||
|
//
|
||||||
|
// You're only an exception to this rule if you fulfil the following criteria:
|
||||||
|
//
|
||||||
|
// - You *really* understand exactly how the versioning system in `helper.rs`
|
||||||
|
// works, what assumptions it makes, and how all of this can go badly wrong.
|
||||||
|
//
|
||||||
|
// - You are creating a new version of a data structure, and *not* modifying an
|
||||||
|
// existing one.
|
||||||
|
//
|
||||||
|
// - You've thought really carefully about things and you've come to the
|
||||||
|
// conclusion that there's just no way to add the feature you want to add
|
||||||
|
// without creating a new version of the data structure in question.
|
||||||
|
//
|
||||||
|
// That said, here's how to make a change to one of the structures in this
|
||||||
|
// module, or submodules.
|
||||||
|
//
|
||||||
|
// 1) Duplicate the latest version of the data structure and the `Version` impl
|
||||||
|
// for it (later versions should be kept at the top of each file).
|
||||||
|
//
|
||||||
|
// 2) Rename the duplicated version, incrementing the version number (i.e: V0
|
||||||
|
// becomes V1).
|
||||||
|
//
|
||||||
|
// 3) Change the `type Prev =` associated type in the new `Version` impl to the
|
||||||
|
// previous versions' type. You will need to write an implementation of
|
||||||
|
// `migrate` that migrates from the old version to the new version.
|
||||||
|
//
|
||||||
|
// 4) *Change* the existing `Latest` impl so that it uses the new version you
|
||||||
|
// have created.
|
||||||
|
//
|
||||||
|
// 5) If your data structure is contained within another data structure, you
|
||||||
|
// will need to similarly update the parent data structure too, also
|
||||||
|
// following these instructions.
|
||||||
|
//
|
||||||
|
// The *golden rule* is that, once merged to master, an old version's type must
|
||||||
|
// not be changed!
|
||||||
|
|
||||||
|
pub mod world;
|
||||||
|
|
||||||
|
use super::{
|
||||||
|
helper::{Bottom, Latest, Version, V},
|
||||||
|
Data,
|
||||||
|
};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
impl Latest<Data> for DataV0 {
|
||||||
|
fn to_unversioned(self) -> Data {
|
||||||
|
Data {
|
||||||
|
world: self.world.to_unversioned(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_unversioned(data: Data) -> Self {
|
||||||
|
Self {
|
||||||
|
world: Latest::from_unversioned(data.world),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct DataV0 {
|
||||||
|
world: V<world::WorldV0>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Version for DataV0 {
|
||||||
|
type Prev = Bottom;
|
||||||
|
|
||||||
|
fn migrate(x: Self::Prev) -> Self { match x {} }
|
||||||
|
}
|
17
rtsim/src/data/version/world.rs
Normal file
17
rtsim/src/data/version/world.rs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
use super::*;
|
||||||
|
use crate::data::World;
|
||||||
|
|
||||||
|
impl Latest<crate::data::World> for WorldV0 {
|
||||||
|
fn to_unversioned(self) -> World { World {} }
|
||||||
|
|
||||||
|
fn from_unversioned(world: World) -> Self { Self {} }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct WorldV0 {}
|
||||||
|
|
||||||
|
impl Version for WorldV0 {
|
||||||
|
type Prev = Bottom;
|
||||||
|
|
||||||
|
fn migrate(x: Self::Prev) -> Self { match x {} }
|
||||||
|
}
|
1
rtsim/src/data/world.rs
Normal file
1
rtsim/src/data/world.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
pub struct World {}
|
7
rtsim/src/lib.rs
Normal file
7
rtsim/src/lib.rs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
pub mod data;
|
||||||
|
|
||||||
|
/*
|
||||||
|
pub struct RtState<'a> {
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
Loading…
Reference in New Issue
Block a user