Added rtsim crate, added initial persistence model

This commit is contained in:
Joshua Barretto 2022-05-15 23:29:21 +01:00
parent 1ea69156da
commit ca80d831ce
9 changed files with 180 additions and 0 deletions

9
Cargo.lock generated
View File

@ -6884,6 +6884,15 @@ dependencies = [
"veloren-plugin-derive",
]
[[package]]
name = "veloren-rtsim"
version = "0.10.0"
dependencies = [
"ron 0.7.0",
"serde",
"veloren-common",
]
[[package]]
name = "veloren-server"
version = "0.14.0"

View File

@ -16,6 +16,7 @@ members = [
"plugin/api",
"plugin/derive",
"plugin/rt",
"rtsim",
"server",
"server/agent",
"server-cli",

9
rtsim/Cargo.toml Normal file
View 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
View 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
View File

@ -0,0 +1,10 @@
pub mod helper;
pub mod version;
pub mod world;
pub use self::world::World;
pub struct Data {
world: World,
}

View 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 {} }
}

View 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
View File

@ -0,0 +1 @@
pub struct World {}

7
rtsim/src/lib.rs Normal file
View File

@ -0,0 +1,7 @@
pub mod data;
/*
pub struct RtState<'a> {
}
*/