1
This commit is contained in:
commit
e52d5f0088
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
target/
|
||||||
|
*.lock
|
||||||
|
#*
|
||||||
|
*#
|
11
f9/Cargo.toml
Normal file
11
f9/Cargo.toml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
[package]
|
||||||
|
name = "f9"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
r9 = { path = "../../r9/r9" }
|
||||||
|
r9_macro = { path = "../../r9/r9_macro" }
|
||||||
|
r9_macro_derive = { path = "../../r9/r9_macro_derive" }
|
105
f9/src/app.rs
Normal file
105
f9/src/app.rs
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
use std::rc::{Rc, Weak};
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::thread::sleep;
|
||||||
|
use std::time::Duration;
|
||||||
|
use r9_macro::SharedFromSelf;
|
||||||
|
use r9_macro_derive::SharedFromSelf;
|
||||||
|
|
||||||
|
pub trait UserApp {
|
||||||
|
fn get_pkg_name(&self) -> String;
|
||||||
|
fn init(&mut self);
|
||||||
|
fn update(&mut self);
|
||||||
|
fn uninit(&mut self);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SharedFromSelf)]
|
||||||
|
pub struct App {
|
||||||
|
_self_wp: Weak::<RefCell::<Self>>,
|
||||||
|
zone_id: i32,
|
||||||
|
node_id: i32,
|
||||||
|
instance_id: i32,
|
||||||
|
user_app: Option<Rc::<RefCell::<dyn UserApp>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl App {
|
||||||
|
|
||||||
|
pub fn instance() -> Rc::<RefCell::<Self>> {
|
||||||
|
static mut _INSTANCE: Option<Rc::<RefCell::<App>>> = None;
|
||||||
|
unsafe {
|
||||||
|
match &_INSTANCE {
|
||||||
|
Some(v) => {
|
||||||
|
return v.clone();
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
_INSTANCE = Some(Rc::new(RefCell::new(
|
||||||
|
App{
|
||||||
|
zone_id: 0,
|
||||||
|
node_id: 0,
|
||||||
|
instance_id: 0,
|
||||||
|
user_app: None,
|
||||||
|
_self_wp: Default::default(),
|
||||||
|
}
|
||||||
|
)));
|
||||||
|
_INSTANCE.clone().unwrap().borrow_mut()._self_wp =
|
||||||
|
Rc::downgrade(&_INSTANCE.clone().unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _INSTANCE.clone().unwrap().clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init(&mut self, user_app: Rc::<RefCell::<dyn UserApp>>) {
|
||||||
|
self.user_app = Some(user_app);
|
||||||
|
crate::Timer::instance().borrow_mut().init();
|
||||||
|
self.user_app.as_ref().unwrap().borrow_mut().init();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn uninit(&mut self) {
|
||||||
|
self.user_app.as_ref().unwrap().borrow_mut().uninit();
|
||||||
|
crate::Timer::instance().borrow_mut().uninit();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run(&mut self) {
|
||||||
|
loop {
|
||||||
|
crate::Timer::instance().borrow_mut().update();
|
||||||
|
sleep(Duration::from_millis(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_pkg_name(&self) -> String {
|
||||||
|
return self.user_app.as_ref().unwrap().borrow().get_pkg_name();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_uuid(&self) -> i64 {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_instance_id(&self) -> i32 {
|
||||||
|
return self.instance_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_zone_id(&self) -> i32 {
|
||||||
|
return self.zone_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_node_id(&self) -> i32 {
|
||||||
|
return self.node_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn has_flag(&self) -> bool {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_now_second(&self) -> i64 {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_now_millis(&self) -> i64 {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_time_offset(&self) -> i64 {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
24
f9/src/lib.rs
Normal file
24
f9/src/lib.rs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
use std::any::{Any};
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
#[test]
|
||||||
|
fn it_works() {
|
||||||
|
let result = 2 + 2;
|
||||||
|
assert_eq!(result, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod timer;
|
||||||
|
pub mod app;
|
||||||
|
|
||||||
|
pub use timer::Timer;
|
||||||
|
//pub use app::app;
|
||||||
|
|
||||||
|
pub struct MsgHdr {
|
||||||
|
pub msg_id: u16,
|
||||||
|
pub seq_id: u32,
|
||||||
|
pub socket_handle: u16,
|
||||||
|
pub msg: dyn Any,
|
||||||
|
|
||||||
|
}
|
115
f9/src/timer.rs
Normal file
115
f9/src/timer.rs
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
use std::rc::{Rc, Weak};
|
||||||
|
use std::any::Any;
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::time::{Instant};
|
||||||
|
use r9::xtimer::{TimerCb, XTimerWp, XTimerAttacherRp, TimerEvent};
|
||||||
|
use r9_macro::SharedFromSelf;
|
||||||
|
use r9_macro_derive::SharedFromSelf;
|
||||||
|
|
||||||
|
pub type TimerWp = XTimerWp;
|
||||||
|
pub type TimerAttacherRp = XTimerAttacherRp;
|
||||||
|
|
||||||
|
#[derive(SharedFromSelf)]
|
||||||
|
pub struct Timer {
|
||||||
|
base: Rc::<RefCell::<r9::xtimer::XTimer>>,
|
||||||
|
_self_wp: Weak::<RefCell::<Self>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Timer {
|
||||||
|
|
||||||
|
pub fn instance() -> Rc::<RefCell::<Self>> {
|
||||||
|
static mut _INSTANCE: Option<Rc::<RefCell::<Timer>>> = None;
|
||||||
|
unsafe {
|
||||||
|
match &_INSTANCE {
|
||||||
|
Some(v) => {
|
||||||
|
return v.clone();
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
_INSTANCE = Some(Rc::new(RefCell::new(
|
||||||
|
Timer{
|
||||||
|
base: r9::xtimer::XTimer::new(),
|
||||||
|
_self_wp: Default::default(),
|
||||||
|
}
|
||||||
|
)));
|
||||||
|
_INSTANCE.clone().unwrap().borrow_mut()._self_wp =
|
||||||
|
Rc::downgrade(&_INSTANCE.clone().unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _INSTANCE.clone().unwrap().clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init(&mut self) {
|
||||||
|
let now = Instant::now();
|
||||||
|
self.base.borrow_mut().init
|
||||||
|
(
|
||||||
|
Box::new(
|
||||||
|
move || -> i64 {
|
||||||
|
//println!("tick:{}", now.elapsed().as_millis());
|
||||||
|
return now.elapsed().as_millis() as i64;
|
||||||
|
}
|
||||||
|
),
|
||||||
|
10,
|
||||||
|
10
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn uninit(&mut self) {
|
||||||
|
self.base.borrow_mut().uninit();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update(&mut self) {
|
||||||
|
r9::xtimer::XTimer::update(&self.base);
|
||||||
|
//return self.base.borrow_mut().update();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_timeout(&mut self, time: i32, cb: TimerCb) -> TimerWp {
|
||||||
|
return self.base.borrow_mut().set_timeout(time, cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_timeout_ex
|
||||||
|
(&mut self, time: i32, cb: TimerCb, attacher: TimerAttacherRp) -> TimerWp {
|
||||||
|
return self.base.borrow_mut().set_timeout_ex(time, cb, attacher);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_interval(&mut self, time: i32, cb: TimerCb) -> TimerWp {
|
||||||
|
return self.base.borrow_mut().set_interval(time, cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_interval_ex
|
||||||
|
(&mut self, time: i32, cb: TimerCb, attacher: TimerAttacherRp) -> TimerWp {
|
||||||
|
return self.base.borrow_mut().set_interval_ex(time, cb, attacher);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fire_event(&mut self,
|
||||||
|
timer_wp: TimerWp,
|
||||||
|
e: TimerEvent,
|
||||||
|
args: Option<Vec<Rc::<dyn Any>>>) {
|
||||||
|
return self.base.borrow_mut().fire_event(timer_wp, e, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn modify(&mut self, timer_wp: TimerWp, expire_time: i32) {
|
||||||
|
self.base.borrow_mut().modify(timer_wp, expire_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn delete_current_timer(&mut self) {
|
||||||
|
self.base.borrow_mut().delete_current_timer();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_running(&self) -> bool {
|
||||||
|
return self.base.borrow().is_running();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn delete(&mut self, timer_wp: TimerWp) {
|
||||||
|
self.base.borrow_mut().delete(timer_wp);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_remain_time(&mut self, timer_wp: TimerWp) -> i64 {
|
||||||
|
return self.base.borrow_mut().get_remain_time(timer_wp);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_idle_time(&self) -> i64 {
|
||||||
|
return self.base.borrow().get_idle_time();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
20
r9/Cargo.toml
Normal file
20
r9/Cargo.toml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
[package]
|
||||||
|
name = "r9"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
#[lib]
|
||||||
|
#proc-macro = true
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
protobuf = "2.9.0"
|
||||||
|
serde = "*"
|
||||||
|
serde_derive = "*"
|
||||||
|
serde_json = "*"
|
||||||
|
syn = "1.0"
|
||||||
|
quote = "1.0"
|
||||||
|
|
||||||
|
r9_macro = { path = "../../r9/r9_macro" }
|
||||||
|
r9_macro_derive = { path = "../../r9/r9_macro_derive" }
|
5
r9/src/lib.rs
Normal file
5
r9/src/lib.rs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
pub mod xtimer;
|
||||||
|
pub mod listhead;
|
||||||
|
|
||||||
|
pub use xtimer::XTimer;
|
||||||
|
pub use listhead::ListHead;
|
96
r9/src/listhead.rs
Normal file
96
r9/src/listhead.rs
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
use std::rc::{Rc, Weak};
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::ptr;
|
||||||
|
use r9_macro::SharedFromSelf;
|
||||||
|
use r9_macro_derive::SharedFromSelf;
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
#[derive(SharedFromSelf)]
|
||||||
|
pub struct ListHead<T> {
|
||||||
|
prev: Weak::<RefCell::<Self>>,
|
||||||
|
next: Weak::<RefCell::<Self>>,
|
||||||
|
data: Weak::<RefCell::<T>>,
|
||||||
|
_self_wp: Weak::<RefCell::<Self>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ListHead<T> {
|
||||||
|
|
||||||
|
fn new(data: Weak::<RefCell::<T>>) -> Rc::<RefCell::<Self>> {
|
||||||
|
let this = Rc::new(RefCell::new(Self{
|
||||||
|
prev: Default::default(),
|
||||||
|
next: Default::default(),
|
||||||
|
data: data,
|
||||||
|
_self_wp: Default::default(),
|
||||||
|
}));
|
||||||
|
this.borrow_mut()._self_wp = Rc::downgrade(&this);
|
||||||
|
this.borrow_mut().init();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_head() -> Rc::<RefCell::<Self>> {
|
||||||
|
return Self::new(Default::default());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_node(data: Weak::<RefCell::<T>>) -> Rc::<RefCell::<Self>> {
|
||||||
|
return Self::new(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init(&mut self) {
|
||||||
|
self.prev = Rc::downgrade(&self.shared_from_self());
|
||||||
|
self.next = Rc::downgrade(&self.shared_from_self());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn data(&self) -> Weak::<RefCell::<T>> {
|
||||||
|
return self.data.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn del_init(&mut self) {
|
||||||
|
self.next.upgrade().unwrap().borrow_mut().prev = self.prev.clone();
|
||||||
|
self.prev.upgrade().unwrap().borrow_mut().next = self.next.clone();
|
||||||
|
self.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn empty(&self) -> bool {
|
||||||
|
return ptr::eq(self.next.as_ptr(), Rc::as_ptr(&self.shared_from_self()));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_tail(head: &Rc::<RefCell::<Self>>, pnew: &Rc::<RefCell::<Self>>) {
|
||||||
|
let prev = &head.borrow_mut().prev.clone();
|
||||||
|
let next = head;
|
||||||
|
|
||||||
|
next.borrow_mut().prev = Rc::downgrade(pnew);
|
||||||
|
pnew.borrow_mut().next = Rc::downgrade(&next);
|
||||||
|
pnew.borrow_mut().prev = prev.clone();
|
||||||
|
prev.upgrade().unwrap().borrow_mut().next = Rc::downgrade(pnew);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn first_entry(&self) -> Weak::<RefCell::<T>> {
|
||||||
|
if self.empty() {
|
||||||
|
panic!("");
|
||||||
|
}
|
||||||
|
return self.next.upgrade().unwrap().borrow().data();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn replace_init(head: &Rc::<RefCell::<Self>>, pnew: &Rc::<RefCell::<Self>>) {
|
||||||
|
if head.borrow().empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pnew.borrow_mut().next = head.borrow().next.clone();
|
||||||
|
pnew.borrow_mut().next.upgrade().unwrap().borrow_mut().prev = Rc::downgrade(pnew);
|
||||||
|
pnew.borrow_mut().prev = head.borrow().prev.clone();
|
||||||
|
pnew.borrow_mut().prev.upgrade().unwrap().borrow_mut().next = Rc::downgrade(pnew);
|
||||||
|
head.borrow_mut().init();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn for_each(&self, cb: fn (&Weak::<RefCell::<T>>) -> bool) {
|
||||||
|
let mut pos = self.next.clone();
|
||||||
|
let self_weak = Rc::downgrade(&self.shared_from_self());
|
||||||
|
while !Weak::ptr_eq(&pos, &self_weak) {
|
||||||
|
if !cb(&pos.upgrade().unwrap().borrow().data()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pos = pos.upgrade().unwrap().borrow().next.clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
539
r9/src/xtimer.rs
Normal file
539
r9/src/xtimer.rs
Normal file
@ -0,0 +1,539 @@
|
|||||||
|
use std::rc::{Rc, Weak};
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::any::Any;
|
||||||
|
use std::cmp;
|
||||||
|
use std::time::{Instant};
|
||||||
|
|
||||||
|
use r9_macro::SharedFromSelf;
|
||||||
|
use r9_macro_derive::SharedFromSelf;
|
||||||
|
|
||||||
|
const TVN_BITS: usize = 6;
|
||||||
|
const TVR_BITS: usize = 8;
|
||||||
|
const TVN_SIZE: usize = 1 << TVN_BITS;
|
||||||
|
const TVR_SIZE: usize = 1 << TVR_BITS;
|
||||||
|
const TVN_MASK: usize = TVN_SIZE - 1;
|
||||||
|
const TVR_MASK: usize = TVR_SIZE - 1;
|
||||||
|
|
||||||
|
pub type XTimerAttacherRp = Rc::<RefCell::<XTimerAttacher>>;
|
||||||
|
pub type XTimerWp = Weak::<Rc::<RefCell::<TimerList>>>;
|
||||||
|
pub type TimerCb = Box::<dyn FnMut (TimerEvent, Option<Vec<Rc::<dyn Any>>>)>;
|
||||||
|
type TimerListListHeadRp = Rc::<RefCell::<crate::ListHead<TimerList>>>;
|
||||||
|
type TimerListRp = Rc::<RefCell::<TimerList>>;
|
||||||
|
type TimerListWp = Weak::<RefCell::<TimerList>>;
|
||||||
|
|
||||||
|
pub enum TimerEvent {
|
||||||
|
Exec,
|
||||||
|
Delete,
|
||||||
|
Destory,
|
||||||
|
Custom(i32)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct XTimerAttacher {
|
||||||
|
timers: TimerListListHeadRp,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
enum TimerType {
|
||||||
|
Timeout,
|
||||||
|
Interval
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for TimerType {
|
||||||
|
|
||||||
|
fn default() -> Self
|
||||||
|
{
|
||||||
|
return TimerType::Timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct TimerList {
|
||||||
|
holder: Option<TimerListRp>,
|
||||||
|
wp: Option<Rc::<TimerListRp>>,
|
||||||
|
timer_entry: TimerListListHeadRp,
|
||||||
|
attach_entry: TimerListListHeadRp,
|
||||||
|
timer_type: TimerType,
|
||||||
|
expire_time: i32,
|
||||||
|
expires: i64,
|
||||||
|
|
||||||
|
cb: Option<TimerCb>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SharedFromSelf)]
|
||||||
|
pub struct XTimer {
|
||||||
|
free_timer_num: i32,
|
||||||
|
free_timer_list: TimerListListHeadRp,
|
||||||
|
running_timer: TimerListWp,
|
||||||
|
timer_tick: i64,
|
||||||
|
get_tick_count: Option<Box<dyn Fn () -> i64>>,
|
||||||
|
cache_timer_num: i32,
|
||||||
|
work_list: TimerListListHeadRp,
|
||||||
|
tv1: Vec<TimerListListHeadRp>,
|
||||||
|
tv2: Vec<TimerListListHeadRp>,
|
||||||
|
tv3: Vec<TimerListListHeadRp>,
|
||||||
|
tv4: Vec<TimerListListHeadRp>,
|
||||||
|
tv5: Vec<TimerListListHeadRp>,
|
||||||
|
_self_wp: Weak::<RefCell::<Self>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl XTimer {
|
||||||
|
|
||||||
|
pub fn new() -> Rc::<RefCell::<Self>> {
|
||||||
|
let this = Rc::new(RefCell::new(XTimer{
|
||||||
|
free_timer_num: 0,
|
||||||
|
free_timer_list: Default::default(),
|
||||||
|
running_timer: Default::default(),
|
||||||
|
timer_tick: Default::default(),
|
||||||
|
get_tick_count: Default::default(),
|
||||||
|
cache_timer_num: 0,
|
||||||
|
work_list: Default::default(),
|
||||||
|
tv1: Vec::with_capacity(TVR_SIZE),
|
||||||
|
tv2: Vec::with_capacity(TVN_SIZE),
|
||||||
|
tv3: Vec::with_capacity(TVN_SIZE),
|
||||||
|
tv4: Vec::with_capacity(TVN_SIZE),
|
||||||
|
tv5: Vec::with_capacity(TVN_SIZE),
|
||||||
|
_self_wp: Default::default(),
|
||||||
|
}));
|
||||||
|
this.borrow_mut()._self_wp = Rc::downgrade(&this);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init(&mut self,
|
||||||
|
get_tick_count: Box<dyn Fn () -> i64>,
|
||||||
|
gctime: i32,
|
||||||
|
cache_timer_num: i32) {
|
||||||
|
self.get_tick_count = Some(get_tick_count);
|
||||||
|
self.cache_timer_num = cache_timer_num;
|
||||||
|
self.free_timer_num = 0;
|
||||||
|
self.free_timer_list = crate::ListHead::<TimerList>::new_head();
|
||||||
|
self.work_list = crate::ListHead::<TimerList>::new_head();
|
||||||
|
for _ in 0..TVR_SIZE {
|
||||||
|
self.tv1.push(crate::ListHead::<TimerList>::new_head());
|
||||||
|
}
|
||||||
|
for _ in 0..TVN_SIZE {
|
||||||
|
self.tv2.push(crate::ListHead::<TimerList>::new_head());
|
||||||
|
self.tv3.push(crate::ListHead::<TimerList>::new_head());
|
||||||
|
self.tv4.push(crate::ListHead::<TimerList>::new_head());
|
||||||
|
self.tv5.push(crate::ListHead::<TimerList>::new_head());
|
||||||
|
}
|
||||||
|
match &self.get_tick_count {
|
||||||
|
Some(v) => {
|
||||||
|
self.timer_tick = (*v)();
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let self_wp = self.shared_from_self();
|
||||||
|
let cb = Box::new(
|
||||||
|
move |event: TimerEvent, args: Option<Vec<Rc::<dyn Any>>>| {
|
||||||
|
self_wp.borrow_mut().gc_timer(event, args);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
self.set_interval(gctime, cb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn traverse_timer_list(&self, cb: &mut dyn FnMut (&TimerListListHeadRp)) {
|
||||||
|
(*cb)(&self.work_list);
|
||||||
|
let mut for_each_cb = |tv: &[TimerListListHeadRp]| {
|
||||||
|
for i in 0..tv.len() {
|
||||||
|
(*cb)(&tv[i]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
for_each_cb(&self.tv1);
|
||||||
|
for_each_cb(&self.tv2);
|
||||||
|
for_each_cb(&self.tv3);
|
||||||
|
for_each_cb(&self.tv4);
|
||||||
|
for_each_cb(&self.tv5);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn uninit(&mut self) {
|
||||||
|
self.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clear(&mut self) {
|
||||||
|
let free_timer = |head: &TimerListListHeadRp| {
|
||||||
|
while !head.borrow().empty() {
|
||||||
|
let timer = &head.borrow().first_entry().upgrade().unwrap();
|
||||||
|
self.detach_timer(timer);
|
||||||
|
if timer.borrow().attach_entry.borrow().empty() {
|
||||||
|
timer.borrow().attach_entry.borrow_mut().del_init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
self.traverse_timer_list(
|
||||||
|
&mut |timer_list: &TimerListListHeadRp| {
|
||||||
|
free_timer(timer_list);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_timer_list(&mut self) -> Rc::<RefCell::<TimerList>> {
|
||||||
|
let p: Rc::<RefCell::<TimerList>>;
|
||||||
|
if !self.free_timer_list.borrow().empty() {
|
||||||
|
p = self.free_timer_list.borrow().first_entry().upgrade().unwrap();
|
||||||
|
if Rc::weak_count(&p.borrow().wp.clone().unwrap()) > 0 {
|
||||||
|
p.borrow_mut().wp = Some(Rc::new(p.borrow().holder.clone().unwrap()));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
p = Rc::new(RefCell::new(TimerList{
|
||||||
|
holder: Default::default(),
|
||||||
|
wp: Default::default(),
|
||||||
|
timer_entry: Default::default(),
|
||||||
|
attach_entry: Default::default(),
|
||||||
|
timer_type: TimerType::Timeout,
|
||||||
|
expire_time: 0,
|
||||||
|
expires: 0,
|
||||||
|
cb: None,
|
||||||
|
}));
|
||||||
|
p.borrow_mut().holder = Some(p.clone());
|
||||||
|
{
|
||||||
|
let z = Some(Rc::new(p.borrow().holder.clone().unwrap()));
|
||||||
|
p.borrow_mut().wp = z;
|
||||||
|
}
|
||||||
|
p.borrow_mut().timer_entry = crate::ListHead::<TimerList>::new_node(
|
||||||
|
Rc::downgrade(&p)
|
||||||
|
);
|
||||||
|
p.borrow_mut().attach_entry = crate::ListHead::<TimerList>::new_head();
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cascade(&self, idx: usize) -> usize {
|
||||||
|
let index = self.get_timer_index(idx);
|
||||||
|
let tv : &[TimerListListHeadRp];
|
||||||
|
match idx {
|
||||||
|
0 => {
|
||||||
|
tv = &self.tv2;
|
||||||
|
}
|
||||||
|
1 => {
|
||||||
|
tv = &self.tv3;
|
||||||
|
}
|
||||||
|
2 => {
|
||||||
|
tv = &self.tv4;
|
||||||
|
}
|
||||||
|
3 => {
|
||||||
|
tv = &self.tv5;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
tv = &self.tv5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !tv[index].borrow().empty() {
|
||||||
|
let cascade_list = crate::ListHead::<TimerList>::new_head();
|
||||||
|
crate::ListHead::<TimerList>::replace_init
|
||||||
|
(&tv[index],
|
||||||
|
&cascade_list);
|
||||||
|
while !cascade_list.borrow().empty() {
|
||||||
|
let timer = &cascade_list.borrow().first_entry().upgrade().unwrap();
|
||||||
|
timer.borrow_mut().timer_entry.borrow_mut().del_init();
|
||||||
|
self.internal_add2(timer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_timer_index(&self, index : usize) -> usize {
|
||||||
|
return ((self.timer_tick as usize) >> (TVR_BITS + index * TVN_BITS)) & TVN_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fetch_work_list(&mut self, tick: i64) -> bool {
|
||||||
|
if tick >= self.timer_tick {
|
||||||
|
let index = (self.timer_tick & (TVR_MASK as i64)) as usize;
|
||||||
|
if index == 0 &&
|
||||||
|
self.cascade(0) == 0 &&
|
||||||
|
self.cascade(1) == 0 &&
|
||||||
|
self.cascade(2) == 0 {
|
||||||
|
self.cascade(3);
|
||||||
|
}
|
||||||
|
self.timer_tick += 1;
|
||||||
|
|
||||||
|
crate::ListHead::<TimerList>::replace_init
|
||||||
|
(&self.tv1[index],
|
||||||
|
&self.work_list);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update(this: &Rc::<RefCell::<XTimer>>) {
|
||||||
|
let tick = (*this.borrow().get_tick_count.as_ref().unwrap())();
|
||||||
|
let work_list = this.borrow().work_list.clone();
|
||||||
|
while this.borrow_mut().fetch_work_list(tick) {
|
||||||
|
while !work_list.borrow().empty() {
|
||||||
|
{
|
||||||
|
let timer = &work_list.borrow().first_entry();
|
||||||
|
this.borrow_mut().running_timer = timer.clone();
|
||||||
|
match &mut timer.upgrade().unwrap().borrow_mut().cb {
|
||||||
|
Some(v) => {
|
||||||
|
(*v)(TimerEvent::Exec, None);
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let running_timer = this.borrow().running_timer.clone();
|
||||||
|
match running_timer.upgrade() {
|
||||||
|
Some(v) => {
|
||||||
|
let timer_wp = Rc::downgrade(&v.borrow().wp.as_ref().unwrap());
|
||||||
|
let timer_type = v.borrow().timer_type.clone();
|
||||||
|
let expire_time = v.borrow().expire_time;
|
||||||
|
match timer_type {
|
||||||
|
TimerType::Timeout => {
|
||||||
|
this.borrow_mut().internal_delete
|
||||||
|
(timer_wp,
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
TimerType::Interval => {
|
||||||
|
this.borrow_mut().internal_modify(
|
||||||
|
timer_wp,
|
||||||
|
expire_time
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.borrow_mut().running_timer = Weak::new();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn internal_add(&mut self,
|
||||||
|
timer_type: TimerType,
|
||||||
|
expire_time: i32,
|
||||||
|
cb: TimerCb,
|
||||||
|
attacher: Option<XTimerAttacherRp>) -> XTimerWp {
|
||||||
|
let t = self.new_timer_list();
|
||||||
|
t.borrow_mut().cb = Some(cb);
|
||||||
|
t.borrow_mut().timer_type = timer_type;
|
||||||
|
t.borrow_mut().expire_time = expire_time;
|
||||||
|
match &self.get_tick_count {
|
||||||
|
Some(v) => {
|
||||||
|
t.borrow_mut().expires = (*v)() + expire_time as i64;
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match attacher {
|
||||||
|
Some(v) => {
|
||||||
|
crate::ListHead::<TimerList>::add_tail
|
||||||
|
(&v.borrow().timers,
|
||||||
|
&t.borrow_mut().attach_entry);
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.internal_add2(&t);
|
||||||
|
return Rc::downgrade(&t.borrow().wp.clone().unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn internal_add2(&self, t: &Rc::<RefCell::<TimerList>>) {
|
||||||
|
let idx = t.borrow().expires - self.timer_tick;
|
||||||
|
let index;
|
||||||
|
let vec: &Rc::<RefCell::<crate::ListHead<TimerList>>>;
|
||||||
|
if idx < 0 {
|
||||||
|
index = self.timer_tick & (TVR_MASK as i64);
|
||||||
|
vec = &self.tv1[index as usize];
|
||||||
|
} else if idx < TVR_SIZE as i64 {
|
||||||
|
index = t.borrow().expires & (TVR_MASK as i64);
|
||||||
|
vec = &self.tv1[index as usize];
|
||||||
|
} else if idx < (1 << (TVR_BITS + TVN_BITS)) {
|
||||||
|
index = (t.borrow().expires >> TVR_BITS) & (TVN_MASK as i64);
|
||||||
|
vec = &self.tv2[index as usize];
|
||||||
|
} else if idx < (1 << (TVR_BITS + 2 * TVN_BITS)) {
|
||||||
|
index = (t.borrow().expires >> (TVR_BITS + 1 * TVN_BITS)) & (TVN_MASK as i64);
|
||||||
|
vec = &self.tv3[index as usize];
|
||||||
|
} else if idx < (1 << (TVR_BITS + 3 * TVN_BITS)) {
|
||||||
|
index = (t.borrow().expires >> (TVR_BITS + 2 * TVN_BITS)) & (TVN_MASK as i64);
|
||||||
|
vec = &self.tv4[index as usize];
|
||||||
|
} else {
|
||||||
|
index = (t.borrow().expires >> (TVR_BITS + 3 * TVN_BITS)) & (TVN_MASK as i64);
|
||||||
|
vec = &self.tv5[index as usize];
|
||||||
|
}
|
||||||
|
crate::ListHead::<TimerList>::add_tail(&vec, &t.borrow_mut().timer_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn internal_delete(&mut self, timer_wp: XTimerWp, is_destory: bool) {
|
||||||
|
match timer_wp.upgrade() {
|
||||||
|
Some(v) => {
|
||||||
|
if Weak::ptr_eq(&self.running_timer, &Rc::downgrade(&v)) {
|
||||||
|
self.running_timer = Weak::new();
|
||||||
|
}
|
||||||
|
self.detach_timer(&*v);
|
||||||
|
match &mut v.borrow_mut().cb {
|
||||||
|
Some(cb) => {
|
||||||
|
if is_destory {
|
||||||
|
(*cb)(TimerEvent::Destory, None);
|
||||||
|
} else {
|
||||||
|
(*cb)(TimerEvent::Delete, None);
|
||||||
|
}
|
||||||
|
v.borrow_mut().cb = None;
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if Rc::weak_count(&v.borrow().wp.clone().unwrap()) > 0 {
|
||||||
|
v.borrow_mut().wp = Some(Rc::new(v.borrow().holder.clone().unwrap()));
|
||||||
|
}
|
||||||
|
crate::ListHead::<TimerList>::add_tail
|
||||||
|
(&self.free_timer_list,
|
||||||
|
&v.borrow_mut().attach_entry);
|
||||||
|
self.free_timer_num += 1;
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn internal_modify(&self, timer_wp: XTimerWp, expire_time: i32) {
|
||||||
|
self.detach_timer(&timer_wp.upgrade().unwrap());
|
||||||
|
let timer = timer_wp.clone().upgrade().unwrap().clone();
|
||||||
|
timer.borrow_mut().expire_time = expire_time;
|
||||||
|
timer.borrow_mut().expires =
|
||||||
|
(*self.get_tick_count.as_ref().unwrap())() +
|
||||||
|
expire_time as i64;
|
||||||
|
self.internal_add2(&timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_timeout(&mut self, time: i32, cb: TimerCb) -> XTimerWp {
|
||||||
|
return self.internal_add(TimerType::Timeout, time, cb, None);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_timeout_ex
|
||||||
|
(&mut self, time: i32, cb: TimerCb, attacher: XTimerAttacherRp) -> XTimerWp {
|
||||||
|
return self.internal_add(TimerType::Timeout, time, cb, Some(attacher));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_interval(&mut self, time: i32, cb: TimerCb) -> XTimerWp {
|
||||||
|
return self.internal_add(TimerType::Interval, time, cb, None);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_interval_ex
|
||||||
|
(&mut self, time: i32, cb: TimerCb, attacher: XTimerAttacherRp) -> XTimerWp {
|
||||||
|
return self.internal_add(TimerType::Interval, time, cb, Some(attacher));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fire_event(&mut self,
|
||||||
|
timer_wp: XTimerWp,
|
||||||
|
e: TimerEvent,
|
||||||
|
args: Option<Vec<Rc::<dyn Any>>>) {
|
||||||
|
match timer_wp.upgrade() {
|
||||||
|
Some(t) => {
|
||||||
|
match &mut t.borrow_mut().cb {
|
||||||
|
Some(cb) => {
|
||||||
|
(*cb)(e, args);
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn modify(&mut self, timer_wp: XTimerWp, expire_time: i32) {
|
||||||
|
match timer_wp.upgrade() {
|
||||||
|
Some(_) => {
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.internal_modify(timer_wp, expire_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn delete_current_timer(&mut self) {
|
||||||
|
match self.running_timer.upgrade() {
|
||||||
|
Some(v) => {
|
||||||
|
self.internal_delete(Rc::downgrade(&v.borrow().wp.clone().unwrap()), false);
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_running(&self) -> bool {
|
||||||
|
match self.running_timer.upgrade() {
|
||||||
|
Some(_) => {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn delete(&mut self, timer_wp: XTimerWp) {
|
||||||
|
match timer_wp.upgrade() {
|
||||||
|
Some(_) => {
|
||||||
|
self.internal_delete(timer_wp, false);
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_remain_time(&mut self, timer_wp: XTimerWp) -> i64 {
|
||||||
|
match timer_wp.upgrade() {
|
||||||
|
Some(t) => {
|
||||||
|
match &self.get_tick_count {
|
||||||
|
Some(v) => {
|
||||||
|
let remain_time = t.borrow().expires - (*v)();
|
||||||
|
return cmp::max(remain_time, 0);
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_idle_time(&self) -> i64 {
|
||||||
|
let mut idle_time = 0;
|
||||||
|
let start_idx = (self.timer_tick as usize) & TVR_MASK;
|
||||||
|
for i in start_idx..self.tv1.len() {
|
||||||
|
if !self.tv1[i].borrow().empty() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
idle_time += 1;
|
||||||
|
}
|
||||||
|
return idle_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gc_timer(&mut self, e: TimerEvent, _args: Option<Vec<Rc::<dyn Any>>>) {
|
||||||
|
let now = Instant::now();
|
||||||
|
//println!("now: {:?}", now);
|
||||||
|
match e {
|
||||||
|
TimerEvent::Exec => {
|
||||||
|
while self.free_timer_num > self.cache_timer_num &&
|
||||||
|
!self.free_timer_list.borrow().empty() {
|
||||||
|
let timer = &self.free_timer_list.borrow().first_entry().upgrade().unwrap();
|
||||||
|
timer.borrow_mut().timer_entry.borrow_mut().del_init();
|
||||||
|
self.free_timer_num -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn detach_timer(&self, timer: &Rc::<RefCell::<TimerList>>) {
|
||||||
|
if !timer.borrow().timer_entry.borrow().empty() {
|
||||||
|
timer.borrow().timer_entry.borrow_mut().del_init()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
8
r9_macro/Cargo.toml
Normal file
8
r9_macro/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "r9_macro"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
18
r9_macro/src/lib.rs
Normal file
18
r9_macro/src/lib.rs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
use std::rc::Rc;
|
||||||
|
use std::cell::RefCell;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
#[test]
|
||||||
|
fn it_works() {
|
||||||
|
let result = 2 + 2;
|
||||||
|
assert_eq!(result, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait SharedFromSelf {
|
||||||
|
fn shared_from_self(&self) -> Rc::<RefCell::<Self>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Singleton {
|
||||||
|
}
|
13
r9_macro_derive/Cargo.toml
Normal file
13
r9_macro_derive/Cargo.toml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
[package]
|
||||||
|
name = "r9_macro_derive"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
proc-macro = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
syn = "1.0"
|
||||||
|
quote = "1.0"
|
68
r9_macro_derive/src/lib.rs
Normal file
68
r9_macro_derive/src/lib.rs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
use proc_macro::TokenStream;
|
||||||
|
use quote::quote;
|
||||||
|
use syn;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
#[test]
|
||||||
|
fn it_works() {
|
||||||
|
let result = 2 + 2;
|
||||||
|
assert_eq!(result, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro_derive(SharedFromSelf, attributes(helper))]
|
||||||
|
pub fn shared_from_self_derive(input: TokenStream) -> TokenStream {
|
||||||
|
let ast = syn::parse(input).unwrap();
|
||||||
|
|
||||||
|
// Build the trait implementation
|
||||||
|
impl_shared_from_self_macro(&ast)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn impl_shared_from_self_macro(ast: &syn::DeriveInput) -> TokenStream {
|
||||||
|
let name = &ast.ident;
|
||||||
|
let (impl_generics, _, _) = ast.generics.split_for_impl();
|
||||||
|
let gen = quote! {
|
||||||
|
impl #impl_generics SharedFromSelf for #name #impl_generics {
|
||||||
|
fn shared_from_self(&self) -> Rc::<RefCell::<Self>> {
|
||||||
|
return self._self_wp.upgrade().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
gen.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro_derive(Singleton)]
|
||||||
|
pub fn singleton_derive(input: TokenStream) -> TokenStream {
|
||||||
|
let ast = syn::parse(input).unwrap();
|
||||||
|
|
||||||
|
// Build the trait implementation
|
||||||
|
impl_singleton_macro(&ast)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn impl_singleton_macro(ast: &syn::DeriveInput) -> TokenStream {
|
||||||
|
let name = &ast.ident;
|
||||||
|
let (_, _, _) = ast.generics.split_for_impl();
|
||||||
|
let gen = quote! {
|
||||||
|
impl #name {
|
||||||
|
pub fn instance() -> Rc::<RefCell::<Self>> {
|
||||||
|
static mut _INSTANCE: Option<Rc::<RefCell::<#name>>> = None;
|
||||||
|
unsafe {
|
||||||
|
match &_INSTANCE {
|
||||||
|
Some(v) => {
|
||||||
|
return v.clone();
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
_INSTANCE = Some(Rc::new(RefCell::new(Self::new())));
|
||||||
|
_INSTANCE.clone().unwrap().borrow_mut()._self_wp =
|
||||||
|
Rc::downgrade(&_INSTANCE.clone().unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _INSTANCE.clone().unwrap().clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
//println!("{}", gen);
|
||||||
|
gen.into()
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user