1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
use anyhow::{Result};
use std::cell::UnsafeCell;
use crate::manager::ObjectManager;
use data_rw::Data;
use data_rw::DataReader;
#[cfg(not(feature ="Arc"))]
pub use sharedptr::Rc::SharedPtr;
#[cfg(not(feature ="Arc"))]
pub use std::rc::Rc;
#[cfg(feature ="Arc")]
pub use sharedptr::Arc::SharedPtr;
#[cfg(feature ="Arc")]
pub use std::sync::Arc;
use std::fmt::Debug;
pub trait ISerdeTypeId{
fn type_id()->u16 where Self: Sized;
fn get_type_id(&self)->u16;
}
#[cfg(not(feature ="Arc"))]
pub trait ISerde:ISerdeTypeId+Debug{
fn write_to(&self,om:&ObjectManager,data:&mut Data)->Result<()>;
fn read_from(&mut self,om:&ObjectManager,data:&mut DataReader)->Result<()>;
fn debug(&self)->String{
format!("{:?}",self)
}
}
#[cfg(feature ="Arc")]
pub trait ISerde:ISerdeTypeId+Debug+Send+Sync{
fn write_to(&self,om:&ObjectManager,data:&mut Data)->Result<()>;
fn read_from(&mut self,om:&ObjectManager,data:&mut DataReader)->Result<()>;
fn debug(&self)->String{
format!("{:?}",self)
}
}
pub trait IStruct{
fn write_to(&self,om:&ObjectManager,data:&mut Data)->Result<()>;
fn read_from(&mut self,om:&ObjectManager,data:&mut DataReader)->Result<()>;
}
pub type CreateFn=fn() -> SharedPtr<dyn ISerde>;
pub struct TypeClass<const LEN:usize>{
pub(crate) register_table:UnsafeCell<[Option<CreateFn>;LEN]>,
pub(crate) register_name:UnsafeCell<Vec<(u16,&'static str)>>
}
unsafe impl<const LEN:usize> Send for TypeClass<LEN>{}
unsafe impl<const LEN:usize> Sync for TypeClass<LEN>{}
impl<const LEN:usize> TypeClass<LEN>{
pub const fn new()->Self {
TypeClass {
register_table:UnsafeCell::new([None;LEN]),
register_name:UnsafeCell::new(Vec::new())
}
}
pub fn register(&self,typeid:u16,name:&'static str,cfn:CreateFn){
unsafe {
(*self.register_table.get())[typeid as usize] = Some(cfn);
(*self.register_name.get()).push((typeid,name));
}
}
#[inline]
#[allow(clippy::manual_map)]
pub fn create(&self,typeid:u16)->Option<SharedPtr<dyn ISerde>>{
unsafe {
if let Some(ref f)=(*self.register_table.get())[typeid as usize]{
Some(f())
}else{
None
}
}
}
}
pub trait ISerdeCaseToType {
fn cast<T: ISerde+'static>(self) -> Result<SharedPtr<T>>
where
Self: Sized;
}
impl ISerdeCaseToType for SharedPtr<dyn ISerde> {
#[inline]
fn cast<T: ISerde+'static>(self) -> Result<SharedPtr<T>> {
anyhow::ensure!(self.get_type_id() == T::type_id(),"case type error {}->{}",self.get_type_id(),T::type_id());
let ptr = &self as *const SharedPtr<dyn ISerde> as *const SharedPtr<T>;
std::mem::forget(self);
unsafe { Ok(ptr.read()) }
}
}
pub trait ITypeCaseToISerde{
fn un_cast(self)-> SharedPtr<dyn ISerde>;
}
impl<T:ISerde+'static> ITypeCaseToISerde for SharedPtr<T>{
#[cfg(not(feature ="Arc"))]
#[inline]
fn un_cast(self) -> SharedPtr<dyn ISerde> {
let ptr = &self as *const SharedPtr<T> as *const Rc<T>;
std::mem::forget(self);
unsafe {
let rc = ptr.read() as Rc<dyn ISerde>;
SharedPtr::from(rc)
}
}
#[cfg(feature ="Arc")]
#[inline]
fn un_cast(self) -> SharedPtr<dyn ISerde> {
let ptr = &self as *const SharedPtr<T> as *const Arc<T>;
std::mem::forget(self);
unsafe {
let rc = ptr.read() as Arc<dyn ISerde>;
SharedPtr::from(rc)
}
}
}