Ver código fonte

智能指针替代读写锁 重构服务端代码 (#15)

R0ronoa 1 ano atrás
pai
commit
282ef85ca1

+ 1 - 33
starry_server/src/base/image.rs

@@ -1,10 +1,4 @@
-use std::{
-    cell::Cell,
-    cmp,
-    fs::File,
-    io::{Seek, SeekFrom, Write},
-    mem, ptr, slice,
-};
+use std::{cell::Cell, cmp, mem, ptr, slice};
 
 use image::GenericImageView;
 use resize::Type;
@@ -339,32 +333,6 @@ impl Image {
         }
     }
 
-    /// 展示在桌面中央
-    pub fn show_on_desktop(&self) {
-        let xoffset = (SCREEN_WIDTH as i32 - self.width()) / 2;
-        let yoffset = (SCREEN_HEIGHT as i32 - self.height()) / 2;
-        let mut fb = File::open("/dev/fb0").expect("[Error] Unable to open framebuffer");
-        for y in 0..self.height() {
-            for x in 0..self.width() {
-                let index: i32 = y * self.width() + x;
-                let offset = ((y + yoffset) * SCREEN_WIDTH as i32 + x + xoffset) * 4;
-                let color = &self.data[index as usize];
-                println!(
-                    "Image show print x:{:?} y:{:?} rgba:{:?} {:?} {:?} {:?}",
-                    x,
-                    y,
-                    color.r(),
-                    color.g(),
-                    color.b(),
-                    color.a()
-                );
-                fb.seek(SeekFrom::Start(offset as u64)).expect("error");
-                fb.write(&self.data[index as usize].to_bgra_bytes())
-                    .expect("error");
-            }
-        }
-    }
-
     /// 改变图像大小
     pub fn resize(&self, w: u32, h: u32, resize_type: Type) -> Self {
         let mut dst_color = vec![Color { data: 0 }; w as usize * h as usize].into_boxed_slice();

+ 27 - 29
starry_server/src/core/compositor.rs

@@ -1,7 +1,8 @@
 use std::{
+    cell::RefCell,
     fs::File,
     io::{Seek, SeekFrom, Write},
-    sync::{Arc, RwLock},
+    sync::Arc,
 };
 
 use starry_client::base::renderer::Renderer;
@@ -12,6 +13,8 @@ use super::{starry_server, window_manager::window_manager, SCREEN_WIDTH};
 
 static mut COMPOSITOR: Option<Arc<Compositor>> = None;
 
+const FB_FILE_PATH: &str = "/dev/fb0";
+
 /// 获得合成渲染器实例
 pub fn compositor() -> Option<Arc<Compositor>> {
     unsafe { COMPOSITOR.clone() }
@@ -20,15 +23,10 @@ pub fn compositor() -> Option<Arc<Compositor>> {
 #[allow(dead_code)]
 /// 合成渲染器
 pub struct Compositor {
-    /// 数据锁
-    data: RwLock<CompositorData>,
-}
-
-pub struct CompositorData {
     /// 待重绘的窗口
-    redraws: Vec<Rect>,
-
-    fb_file: File,
+    redraws: RefCell<Vec<Rect>>,
+    /// 帧缓冲文件
+    fb_file: RefCell<File>,
 }
 
 #[allow(dead_code)]
@@ -36,10 +34,10 @@ impl Compositor {
     /// 创建合成渲染器
     pub fn new() {
         let compositor = Compositor {
-            data: RwLock::new(CompositorData {
-                redraws: Vec::new(),
-                fb_file: File::open("/dev/fb0").expect("[Error] Unable to open framebuffer"),
-            }),
+            redraws: RefCell::new(Vec::new()),
+            fb_file: RefCell::new(
+                File::open(FB_FILE_PATH).expect("[Error] Compositor failed to open fb file"),
+            ),
         };
 
         unsafe {
@@ -60,12 +58,8 @@ impl Compositor {
         // 对窗口排序
         window_manager.rezbuffer();
 
-        let mut window_manager_guard = window_manager.data.write().unwrap();
-        let mut compositor_guard = self.data.write().unwrap();
-        let mut server_guard = server.data.write().unwrap();
-
         let mut total_redraw_rect_opt: Option<Rect> = None;
-        for original_rect in compositor_guard.redraws.drain(..) {
+        for original_rect in self.redraws.borrow_mut().drain(..) {
             // 更新重绘的总矩形区域
             if !original_rect.is_empty() {
                 total_redraw_rect_opt = match total_redraw_rect_opt {
@@ -74,20 +68,21 @@ impl Compositor {
                 }
             }
 
-            let mut cursors = server_guard.cursors.clone();
             // 遍历所有显示窗口
-            for display in server_guard.displays.iter_mut() {
+            for display in server.displays.borrow_mut().iter_mut() {
                 let rect = original_rect.intersection(&display.screen_rect());
                 if !rect.is_empty() {
                     // TODO: 填充默认颜色
 
                     // 倒序渲染所有窗口
-                    let len = window_manager_guard.zbuffer.len();
+                    let zbuffer = window_manager.zbuffer.borrow_mut();
+                    let len = zbuffer.len();
                     for index in (0..len).rev() {
-                        let entry = window_manager_guard.zbuffer.get(index).unwrap();
+                        let entry = zbuffer.get(index).unwrap();
                         let _id = entry.0;
                         let index = entry.2;
-                        if let Some(window) = window_manager_guard.windows.get_mut(&index) {
+                        let mut windows = window_manager.windows.borrow_mut();
+                        if let Some(window) = windows.get_mut(&index) {
                             // TODO: 渲染窗口标题
 
                             // 渲染窗体
@@ -98,7 +93,11 @@ impl Compositor {
 
                 let cursor_intersect = rect.intersection(&cursor_rect);
                 if !cursor_intersect.is_empty() {
-                    if let Some(cursor) = cursors.get_mut(&window_manager_guard.cursor_i) {
+                    if let Some(cursor) = server
+                        .cursors
+                        .borrow_mut()
+                        .get_mut(&window_manager.cursor_i.get())
+                    {
                         display.roi(&cursor_intersect).blend(&cursor.roi(
                             &cursor_intersect.offset(-cursor_rect.left(), -cursor_rect.top()),
                         ));
@@ -110,10 +109,10 @@ impl Compositor {
         // println!("[Info] Compositor calculate total redraw rect done!");
 
         // TODO
-        let mut fb = &compositor_guard.fb_file;
+        let mut fb = self.fb_file.borrow_mut();
 
         if let Some(total_redraw_rect) = total_redraw_rect_opt {
-            for display in server_guard.displays.iter_mut() {
+            for display in server.displays.borrow_mut().iter_mut() {
                 let display_redraw = total_redraw_rect.intersection(&display.screen_rect());
                 if !display_redraw.is_empty() {
                     for y in 0..display_redraw.height() {
@@ -140,10 +139,9 @@ impl Compositor {
     /// 窗口请求重绘
     pub fn request_redraw(&self, rect: Rect) {
         // println!("[Info] Compositor request redraw rect {:?}", rect);
-        let mut guard = self.data.write().unwrap();
         let mut push = true;
 
-        for rect in guard.redraws.iter_mut() {
+        for rect in self.redraws.borrow_mut().iter_mut() {
             let container = rect.container(&rect);
             if container.area() <= rect.area() + rect.area() {
                 *rect = container;
@@ -152,7 +150,7 @@ impl Compositor {
         }
 
         if push {
-            guard.redraws.push(rect);
+            self.redraws.borrow_mut().push(rect);
         }
     }
 }

+ 4 - 16
starry_server/src/core/input/mod.rs

@@ -1,8 +1,4 @@
-use std::{
-    fs::File,
-    io::Read,
-    sync::{Arc, RwLock},
-};
+use std::{cell::RefCell, fs::File, io::Read, sync::Arc};
 
 use starry_client::base::event::Event;
 
@@ -21,13 +17,8 @@ pub fn input_manager() -> Option<Arc<InputManager>> {
 /// 输入管理器
 #[allow(dead_code)]
 pub struct InputManager {
-    /// 数据锁
-    data: RwLock<InputManagerData>,
-}
-
-pub struct InputManagerData {
     /// 轮询的文件数组
-    handlers: Vec<Box<dyn InputHandler>>,
+    handlers: RefCell<Vec<Box<dyn InputHandler>>>,
 }
 
 impl InputManager {
@@ -38,9 +29,7 @@ impl InputManager {
         input_handlers.push(MouseInputHandler::new() as Box<dyn InputHandler>);
         // TODO: 处理键盘输入
         let input_manager = InputManager {
-            data: RwLock::new(InputManagerData {
-                handlers: input_handlers,
-            }),
+            handlers: RefCell::new(input_handlers),
         };
 
         unsafe {
@@ -53,8 +42,7 @@ impl InputManager {
     /// 轮询所有输入设备
     pub fn polling_all(&self) {
         // println!("[Info] Input_Manager polling all");
-        let mut guard = self.data.write().unwrap();
-        for handle in guard.handlers.iter_mut() {
+        for handle in self.handlers.borrow_mut().iter_mut() {
             handle.polling();
         }
     }

+ 8 - 20
starry_server/src/core/mod.rs

@@ -1,8 +1,4 @@
-use std::{
-    collections::BTreeMap,
-    rc::Rc,
-    sync::{Arc, RwLock},
-};
+use std::{cell::RefCell, collections::BTreeMap, sync::Arc};
 
 use crate::{
     base::{display::Display, image::Image},
@@ -37,20 +33,14 @@ pub fn starry_server() -> Option<Arc<StarryServer>> {
 
 /// 图形系统服务器
 pub struct StarryServer {
-    /// 数据锁
-    data: RwLock<StarryServerData>,
-}
-
-pub struct StarryServerData {
-    /// 窗口数组
-    pub displays: Vec<Display>,
-    pub config: Rc<Config>,
-    pub cursors: BTreeMap<CursorKind, Image>,
+    pub displays: RefCell<Vec<Display>>,
+    pub config: RefCell<Arc<Config>>,
+    pub cursors: RefCell<BTreeMap<CursorKind, Image>>,
 }
 
 impl StarryServer {
     /// 创建图形服务器
-    pub fn new(config: Rc<Config>, displays: Vec<Display>) {
+    pub fn new(config: Arc<Config>, displays: Vec<Display>) {
         let mut cursors = BTreeMap::new();
         cursors.insert(CursorKind::None, Image::new(0, 0));
         cursors.insert(
@@ -64,11 +54,9 @@ impl StarryServer {
         // cursors.insert(CursorKind::RightSide, Image::from_path_scale(&config.right_side, scale).unwrap_or(Image::new(0, 0)));
 
         let server = StarryServer {
-            data: RwLock::new(StarryServerData {
-                displays: displays,
-                config: Rc::clone(&config),
-                cursors: cursors,
-            }),
+            displays: RefCell::new(displays),
+            config: RefCell::new(config),
+            cursors: RefCell::new(cursors),
         };
 
         unsafe {

+ 70 - 118
starry_server/src/core/window_manager.rs

@@ -1,7 +1,8 @@
 use std::{
+    cell::{Cell, RefCell},
     cmp,
     collections::{BTreeMap, VecDeque},
-    sync::{Arc, RwLock},
+    sync::Arc,
 };
 
 use starry_client::base::event::{Event, EventOption, MouseRelativeEvent, MouseUpdateEvent};
@@ -45,49 +46,41 @@ pub enum CursorKind {
 /// 窗口管理器
 #[allow(dead_code)]
 pub struct WindowManager {
-    /// 数据锁
-    pub data: RwLock<WindowManagerData>,
-}
-
-#[allow(dead_code)]
-pub struct WindowManagerData {
     /// 下一个窗口的id值
-    next_id: isize,
+    next_id: Cell<isize>,
     /// TODO
-    _hover: Option<usize>,
+    _hover: RefCell<Option<usize>>,
     /// 窗口顺序
-    pub order: VecDeque<usize>,
+    pub order: RefCell<VecDeque<usize>>,
     /// 窗口顺序信息(下标index,模式,窗口id)
-    pub zbuffer: Vec<(usize, WindowZOrderMode, usize)>,
+    pub zbuffer: RefCell<Vec<(usize, WindowZOrderMode, usize)>>,
     /// 窗口字典
-    pub windows: BTreeMap<usize, Window>,
+    pub windows: RefCell<BTreeMap<usize, Window>>,
 
     /// 鼠标x坐标
-    pub cursor_x: i32,
+    pub cursor_x: Cell<i32>,
     /// 鼠标y坐标
-    pub cursor_y: i32,
+    pub cursor_y: Cell<i32>,
     /// 鼠标状态
-    pub cursor_i: CursorKind,
+    pub cursor_i: Cell<CursorKind>,
 
     /// 待处理的事件数组
-    events: Vec<Event>,
+    events: RefCell<Vec<Event>>,
 }
 
 impl WindowManager {
     /// 创建窗口管理器
     pub fn new() {
         let window_manager = WindowManager {
-            data: RwLock::new(WindowManagerData {
-                next_id: 0,
-                _hover: None,
-                order: VecDeque::new(),
-                zbuffer: Vec::new(),
-                windows: BTreeMap::new(),
-                cursor_x: SCREEN_WIDTH as i32 / 2,
-                cursor_y: SCREEN_HEIGHT as i32 / 2,
-                cursor_i: CursorKind::None,
-                events: Vec::new(),
-            }),
+            next_id: Cell::new(0),
+            _hover: RefCell::new(None),
+            order: RefCell::new(VecDeque::new()),
+            zbuffer: RefCell::new(Vec::new()),
+            windows: RefCell::new(BTreeMap::new()),
+            cursor_x: Cell::new(SCREEN_WIDTH as i32 / 2),
+            cursor_y: Cell::new(SCREEN_HEIGHT as i32 / 2),
+            cursor_i: Cell::new(CursorKind::Normal),
+            events: RefCell::new(Vec::new()),
         };
 
         unsafe {
@@ -120,77 +113,62 @@ impl WindowManager {
         _title: String,
         image_path: &[u8],
     ) {
-        let mouse_update_event: MouseUpdateEvent;
+        let compositor = compositor().unwrap();
 
-        {
-            let compositor = compositor().unwrap();
-            let mut guard = self.data.write().unwrap();
+        let id = self.next_id.get() as usize; // 新窗口的id
+        self.next_id.set(self.next_id.get() + 1);
 
-            let id = guard.next_id as usize; // 新窗口的id
-            guard.next_id += 1;
-
-            if guard.next_id < 0 {
-                guard.next_id = 1;
-            }
+        if self.next_id.get() < 0 {
+            self.next_id.set(1);
+        }
 
-            if x < 0 && y < 0 {
-                x = cmp::max(0, (SCREEN_WIDTH as i32 - width) / 2);
-                y = cmp::max(0, (SCREEN_HEIGHT as i32 - height) / 2);
-            }
+        if x < 0 && y < 0 {
+            x = cmp::max(0, (SCREEN_WIDTH as i32 - width) / 2);
+            y = cmp::max(0, (SCREEN_HEIGHT as i32 - height) / 2);
+        }
 
-            // TODO 传入正确的scale
-            // TODO 传入title
-            let window = Window::new(x, y, width, height, 1, image_path);
+        // TODO 传入正确的scale
+        // TODO 传入title
+        let window = Window::new(x, y, width, height, 1, image_path);
 
-            // TODO 处理flags
+        // TODO 处理flags
 
-            // TODO 重绘title_rect
-            compositor.request_redraw(window.rect());
+        // TODO 重绘title_rect
+        compositor.request_redraw(window.rect());
 
-            match window.zorder {
-                WindowZOrderMode::Front | WindowZOrderMode::Normal => {
-                    guard.order.push_front(id);
-                }
-                WindowZOrderMode::Back => {
-                    guard.order.push_back(id);
-                }
+        match window.zorder {
+            WindowZOrderMode::Front | WindowZOrderMode::Normal => {
+                self.order.borrow_mut().push_front(id);
+            }
+            WindowZOrderMode::Back => {
+                self.order.borrow_mut().push_back(id);
             }
+        }
 
-            guard.windows.insert(id, window);
+        self.windows.borrow_mut().insert(id, window);
 
-            // 确保鼠标正确显示
-            mouse_update_event = MouseUpdateEvent {
-                x: guard.cursor_x,
-                y: guard.cursor_y,
-            };
-        }
+        // 确保鼠标正确显示
+        let mouse_update_event = MouseUpdateEvent {
+            x: self.cursor_x.get(),
+            y: self.cursor_y.get(),
+        };
 
         self.handle_mouse_update_event(mouse_update_event);
     }
 
     /// 发送事件
     pub fn send_event(&self, event: Event) {
-        let mut guard = self.data.write().unwrap();
-        guard.events.push(event);
+        self.events.borrow_mut().push(event);
     }
 
     /// 发送事件数组
     pub fn send_events(&self, mut events: Vec<Event>) {
-        let mut guard = self.data.write().unwrap();
-        guard.events.append(&mut events);
+        self.events.borrow_mut().append(&mut events);
     }
 
     /// 处理所有事件
     pub fn handle_all_events(&self) {
-        let mut events: Vec<Event>;
-
-        {
-            let mut guard = self.data.write().unwrap();
-            events = guard.events.clone();
-            guard.events.clear();
-        }
-
-        while let Some(event) = events.pop() {
+        while let Some(event) = self.events.borrow_mut().pop() {
             self.handle_event(event);
         }
     }
@@ -213,15 +191,6 @@ impl WindowManager {
     pub fn handle_mouse_relative_event(&self, event: MouseRelativeEvent) {
         // TODO: 将事件传递给窗口,同时考虑窗口对鼠标位置的影响
 
-        let cursor_x: i32;
-        let cursor_y: i32;
-
-        {
-            let guard = self.data.read().unwrap();
-            cursor_x = guard.cursor_x;
-            cursor_y = guard.cursor_y;
-        }
-
         let max_x: i32 = SCREEN_WIDTH as i32;
         let max_y: i32 = SCREEN_HEIGHT as i32;
         let cursor_rect = self.cursor_rect();
@@ -229,11 +198,11 @@ impl WindowManager {
         //防止鼠标出界
         let x = cmp::max(
             0,
-            cmp::min(max_x - cursor_rect.width(), cursor_x + event.dx),
+            cmp::min(max_x - cursor_rect.width(), self.cursor_x.get() + event.dx),
         );
         let y = cmp::max(
             0,
-            cmp::min(max_y - cursor_rect.height(), cursor_y - event.dy),
+            cmp::min(max_y - cursor_rect.height(), self.cursor_y.get() - event.dy),
         ); // 原点在左上角,向上为负
 
         self.handle_mouse_update_event(MouseUpdateEvent { x, y });
@@ -259,27 +228,13 @@ impl WindowManager {
     fn update_cursor(&self, x: i32, y: i32, kind: CursorKind) {
         // println!("[Info] Mouse_Input_Handler update cursor {:?} {:?} ", x, y);
 
-        let old_cursor_x: i32;
-        let old_cursor_y: i32;
-        let old_cursor_i: CursorKind;
-
-        {
-            let guard = self.data.read().unwrap();
-            old_cursor_x = guard.cursor_x;
-            old_cursor_y = guard.cursor_y;
-            old_cursor_i = guard.cursor_i;
-        }
-
-        if kind != old_cursor_i || x != old_cursor_x || y != old_cursor_y {
+        if kind != self.cursor_i.get() || x != self.cursor_x.get() || y != self.cursor_y.get() {
             let cursor_rect = self.cursor_rect();
             compositor().unwrap().request_redraw(cursor_rect);
 
-            {
-                let mut guard = self.data.write().unwrap();
-                guard.cursor_x = x;
-                guard.cursor_y = y;
-                guard.cursor_i = kind;
-            }
+            self.cursor_i.set(kind);
+            self.cursor_x.set(x);
+            self.cursor_y.set(y);
 
             let cursor_rect = self.cursor_rect();
             compositor().unwrap().request_redraw(cursor_rect);
@@ -289,40 +244,37 @@ impl WindowManager {
     /// # 函数功能
     /// 获得鼠标位置的矩形区域
     pub fn cursor_rect(&self) -> Rect {
-        let guard = self.data.read().unwrap();
         let server = starry_server().unwrap();
-        let server_gaurd = server.data.read().unwrap();
 
-        if let Some(image) = server_gaurd.cursors.get(&guard.cursor_i) {
+        if let Some(image) = server.cursors.borrow().get(&self.cursor_i.get()) {
             return Rect::new(
-                guard.cursor_x,
-                guard.cursor_y,
+                self.cursor_x.get(),
+                self.cursor_y.get(),
                 image.width(),
                 image.height(),
             );
         }
 
-        return Rect::new(guard.cursor_x, guard.cursor_y, 0, 0);
+        return Rect::new(self.cursor_x.get(), self.cursor_y.get(), 0, 0);
     }
 
     /// 更新zbuffer
     pub fn rezbuffer(&self) {
-        let mut guard = self.data.write().unwrap();
-
-        guard.zbuffer.clear();
+        self.zbuffer.borrow_mut().clear();
 
-        let len = guard.order.len();
-        for index in 0..len {
-            let id = guard.order[index];
-            let window_z = guard
+        let order = self.order.borrow_mut();
+        for index in 0..order.len() {
+            let id = order[index];
+            let window_z = self
                 .windows
+                .borrow()
                 .get(&index)
                 .expect("窗口不存在!")
                 .zorder
                 .clone();
-            guard.zbuffer.push((id, window_z, index));
+            self.zbuffer.borrow_mut().push((id, window_z, index));
         }
 
-        guard.zbuffer.sort_by(|a, b| b.1.cmp(&a.1));
+        self.zbuffer.borrow_mut().sort_by(|a, b| b.1.cmp(&a.1));
     }
 }

+ 2 - 2
starry_server/src/main.rs

@@ -1,4 +1,4 @@
-use std::rc::Rc;
+use std::sync::Arc;
 
 use starry_server::{
     base::display::Display,
@@ -17,7 +17,7 @@ fn main() {
     ));
 
     // TODO 暂时不考虑配置文件
-    let config: Rc<Config> = Rc::new(Config::default());
+    let config: Arc<Config> = Arc::new(Config::default());
 
     //开启Starry Server
     StarryServer::new(config, displays);