Commit e60fc603 authored by Florian Blasius's avatar Florian Blasius 🤘

[#168] work on backend refactoring.

parent c12497b7
......@@ -18,7 +18,8 @@
"group": {
"kind": "build",
"isDefault": true
}
},
"problemMatcher": []
},
{
"label": "build debug",
......
......@@ -475,6 +475,7 @@ dependencies = [
"orbgl_api 0.1.0 (git+https://gitlab.redox-os.org/redox-os/orbgl.git)",
"orbimage 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
"orbtk-css-engine 0.1.0",
"orbtk-shell 0.1.0",
"orbtk-theme 0.1.0",
"orbtk-tree 0.1.0",
"orbtk-utils 0.1.0",
......@@ -488,6 +489,16 @@ dependencies = [
"orbtk-utils 0.1.0",
]
[[package]]
name = "orbtk-shell"
version = "0.1.0"
dependencies = [
"orbclient 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
"orbfont 0.1.9 (git+https://gitlab.redox-os.org/redox-os/orbfont.git)",
"orbgl 0.1.0 (git+https://gitlab.redox-os.org/redox-os/orbgl.git)",
"orbgl_api 0.1.0 (git+https://gitlab.redox-os.org/redox-os/orbgl.git)",
]
[[package]]
name = "orbtk-theme"
version = "0.1.0"
......
......@@ -29,6 +29,7 @@ orbclient = "0.3.22"
[dependencies]
orbtk-css-engine = { version = "0.1.0", path = "crates/css-engine" }
orbtk-shell = { version = "0.1.0", path = "crates/shell" }
orbtk-theme = { version = "0.1.0", path="crates/theme" }
orbtk-utils = { version = "0.1.0", path = "crates/utils" }
orbtk-tree = { version = "0.1.0", path="crates/tree" }
......@@ -45,6 +46,7 @@ debug = []
[workspace]
members = [
"crates/css-engine",
"crates/shell",
"crates/theme",
"crates/utils",
"crates/tree"
......
[package]
name = "orbtk-shell"
version = "0.1.0"
authors = ["Florian Blasius <flovanpt@posteo.de>"]
description = "Window shell crate used by OrbTk."
repository = "https://gitlab.redox-os.org/redox-os/orbtk"
license = "MIT"
keywords = ["shell", "window", "ui"]
edition = "2018"
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
orbgl = { git = "https://gitlab.redox-os.org/redox-os/orbgl.git" }
orbfont = { git = "https://gitlab.redox-os.org/redox-os/orbfont.git" }
orbclient = "0.3.22"
[dependencies]
orbgl_api = { git = "https://gitlab.redox-os.org/redox-os/orbgl.git" }
/*!
Window shell abstraction layer used by OrbTk.
*/
use orbgl_api::Canvas;
pub use self::platform::*;
pub use self::update::*;
pub mod prelude;
mod update;
#[cfg(not(target_arch = "wasm32"))]
#[path = "orbclient/mod.rs"]
mod platform;
pub trait WindowShell {
fn adapter(&mut self, adapter: impl Into<Box<WindowAdapter>>);
fn canvas(&mut self) -> &mut Canvas;
fn run(&mut self);
}
pub trait WindowAdapter {
fn resize(&mut self);
fn update(&mut self);
}
use crate::{Update, Runner};
impl Runner for Update {
fn run(&mut self) {
loop {
if !(self.update)() {
break;
}
}
}
}
\ No newline at end of file
/// Update is used to call the registered update function in a loop
/// that depends on the used platform.
pub struct Update {
pub update: Box<FnMut() -> bool + Send>,
}
impl Update {
pub fn new(update: Box<FnMut() -> bool + Send>) -> Self {
Update {
update
}
}
}
/// This trait is used to define an update loop.
pub trait Runner {
fn run(&mut self);
}
\ No newline at end of file
......@@ -64,17 +64,18 @@ impl Application {
world.entity_component_manager().register_component(window, Global::default());
world.entity_component_manager().register_component(window, Bounds::from((0.0, 0.0, constraint.width(), constraint.height())));
let (mut runner, backend) =
target_backend(&title.0, Bounds::from((position.0.x, position.0.y, constraint.width(), constraint.height())), false);
let window_shell = Rc::new(RefCell::new(WindowBuilder::new().title(&(title.0)[..]).bounds(Bounds::from((position.0.x, position.0.y, constraint.width(), constraint.height()))).resizeable(resizeable.0).build()));
// let (mut runner, backend) =
// target_backend(&(title.0)[..], Bounds::from((position.0.x, position.0.y, constraint.width(), constraint.height())), false);
world.register_init_system(InitSystem {
backend: backend.clone(),
backend: window_shell.clone(),
states: states.clone(),
});
world
.create_system(EventSystem {
backend: backend.clone(),
backend: window_shell.clone(),
handlers: handlers.clone(),
update: update.clone(),
running: running.clone(),
......@@ -84,7 +85,7 @@ impl Application {
world
.create_system(StateSystem {
backend: backend.clone(),
backend: window_shell.clone(),
states: states.clone(),
update: update.clone(),
running: running.clone(),
......@@ -94,7 +95,7 @@ impl Application {
world
.create_system(LayoutSystem {
backend: backend.clone(),
backend: window_shell.clone(),
layouts: layouts.clone(),
update: update.clone(),
running: running.clone(),
......@@ -104,7 +105,7 @@ impl Application {
world
.create_system(PostLayoutStateSystem {
backend: backend.clone(),
backend: window_shell.clone(),
states: states.clone(),
update: update.clone(),
running: running.clone(),
......@@ -114,7 +115,7 @@ impl Application {
world
.create_system(RenderSystem {
backend: backend.clone(),
backend: window_shell.clone(),
render_objects: render_objects.clone(),
update: update.clone(),
running: running.clone(),
......@@ -122,10 +123,13 @@ impl Application {
.with_priority(4)
.build();
runner.world(world);
self.windows.push(WindowShell {
backend_runner: runner,
backend_runner: ShellRunner {
world: Some(world),
window_shell
},
render_objects,
layouts,
handlers,
......
......@@ -11,7 +11,7 @@ use crate::backend::*;
/// Represents a window. Each window has its own tree, event pipeline and backend.
pub struct WindowShell {
pub backend_runner: Box<dyn BackendRunner>,
pub backend_runner: ShellRunner,
pub render_objects: Rc<RefCell<BTreeMap<Entity, Box<dyn RenderObject>>>>,
pub layouts: Rc<RefCell<BTreeMap<Entity, Box<dyn Layout>>>>,
pub handlers: Rc<RefCell<BTreeMap<Entity, Vec<Rc<dyn EventHandler>>>>>,
......
......@@ -56,7 +56,7 @@ pub trait Backend {
}
/// This trait is used to create a backend runner.
pub trait BackendRunner {
pub trait Runner {
fn world(&mut self, world: World<Tree>);
fn run(&mut self, update: Rc<Cell<bool>>, running: Rc<Cell<bool>>);
}
......@@ -66,7 +66,7 @@ pub trait FontMeasure {
fn measure(&self, text: &str, font: &Font, font_size: u32) -> (u32, u32);
}
pub use self::target::target_backend;
pub use self::target::{WindowBuilder, ShellRunner, OrbitalBackend};
pub use self::target::FONT_MEASURE;
#[cfg(not(target_arch = "wasm32"))]
......
......@@ -2,7 +2,7 @@ use std::cell::{Cell, RefCell};
use std::collections::BTreeMap;
use std::rc::Rc;
use orbclient::{self, Renderer as OrbRenderer, Window as OrbWindow};
use orbclient::{self, Renderer as OrbRenderer, Window as OrbWindow, WindowFlag};
use dces::prelude::{Entity, World};
use orbgl::prelude::{CairoRenderEngine, FramebufferSurface};
......@@ -43,16 +43,8 @@ impl OrbitalBackend {
canvas,
}
}
}
impl Drop for OrbitalBackend {
fn drop(&mut self) {
self.inner.sync();
}
}
impl Backend for OrbitalBackend {
fn drain_events(&mut self) {
pub fn drain_events(&mut self) {
self.inner.sync();
for event in self.inner.events() {
......@@ -149,7 +141,7 @@ impl Backend for OrbitalBackend {
}
}
fn render_context(&mut self) -> RenderContext<'_> {
pub fn render_context(&mut self) -> RenderContext<'_> {
RenderContext {
canvas: &mut self.canvas,
renderer: &mut self.inner,
......@@ -157,13 +149,13 @@ impl Backend for OrbitalBackend {
}
}
fn event_context(&mut self) -> EventContext<'_> {
pub fn event_context(&mut self) -> EventContext<'_> {
EventContext {
event_queue: &self.event_queue,
}
}
fn state_context(&mut self) -> StateContext<'_> {
pub fn state_context(&mut self) -> StateContext<'_> {
StateContext {
event_queue: &self.event_queue,
messages: &mut self.messages,
......@@ -171,18 +163,24 @@ impl Backend for OrbitalBackend {
}
}
impl Drop for OrbitalBackend {
fn drop(&mut self) {
self.inner.sync();
}
}
// impl Backend for OrbitalBackend {
// }
/// Implementation of the OrbClient based backend runner.
pub struct OrbitalBackendRunner {
pub struct ShellRunner {
pub world: Option<World<Tree>>,
pub backend: Rc<RefCell<OrbitalBackend>>,
pub window_shell: Rc<RefCell<OrbitalBackend>>,
}
impl BackendRunner for OrbitalBackendRunner {
fn world(&mut self, world: World<Tree>) {
self.world = Some(world);
}
fn run(&mut self, update: Rc<Cell<bool>>, running: Rc<Cell<bool>>) {
impl ShellRunner {
pub fn run(&mut self, update: Rc<Cell<bool>>, running: Rc<Cell<bool>>) {
loop {
if !running.get() {
break;
......@@ -194,7 +192,56 @@ impl BackendRunner for OrbitalBackendRunner {
update.set(false);
self.backend.borrow_mut().drain_events();
self.window_shell.borrow_mut().drain_events();
}
}
}
#[derive(Default)]
pub struct WindowBuilder {
title: String,
resizeable: bool,
bounds: Bounds,
}
impl WindowBuilder {
pub fn new() -> Self {
WindowBuilder::default()
}
pub fn title(mut self, title: impl Into<String>) -> Self {
self.title = title.into();
self
}
pub fn resizeable(mut self, resizeable: bool) -> Self {
self.resizeable = resizeable;
self
}
pub fn bounds(mut self, bounds: impl Into<Bounds>) -> Self {
self.bounds = bounds.into();
self
}
pub fn build(self) -> OrbitalBackend {
let mut flags = vec![];
if self.resizeable {
flags.push(WindowFlag::Resizable);
}
OrbitalBackend::new(
OrbWindow::new_flags(
self.bounds.x() as i32,
self.bounds.y() as i32,
self.bounds.width() as u32,
self.bounds.height() as u32,
&self.title,
&flags,
)
.unwrap(),
)
}
}
\ No newline at end of file
......@@ -7,41 +7,42 @@ use std::sync::Arc;
use orbclient::{Window as OrbWindow, WindowFlag};
use orbfont::Font;
use self::backend::{OrbitalBackend, OrbitalBackendRunner};
pub use self::backend::{WindowBuilder, OrbitalBackend, ShellRunner};
use crate::backend::*;
mod backend;
mod renderer;
pub fn target_backend(
title: &str,
bounds: Bounds,
resizable: bool,
) -> (Box<OrbitalBackendRunner>, Rc<RefCell<dyn Backend>>) {
let mut flags = vec![];
if resizable {
flags.push(WindowFlag::Resizable);
}
let backend = Rc::new(RefCell::new(OrbitalBackend::new(
OrbWindow::new_flags(
bounds.x() as i32,
bounds.y() as i32,
bounds.width() as u32,
bounds.height() as u32,
title,
&flags,
)
.unwrap(),
)));
let backend_runner = Box::new(OrbitalBackendRunner {
backend: backend.clone(),
world: None,
});
(backend_runner, backend)
}
// pub fn target_backend(
// title: &str,
// bounds: Bounds,
// resizable: bool,
// ) -> (Box<ShellRunner>, Rc<RefCell<dyn Backend>>) {
// let mut flags = vec![];
// if resizable {
// flags.push(WindowFlag::Resizable);
// }
// let backend = Rc::new(RefCell::new(OrbitalBackend::new(
// OrbWindow::new_flags(
// bounds.x() as i32,
// bounds.y() as i32,
// bounds.width() as u32,
// bounds.height() as u32,
// title,
// &flags,
// )
// .unwrap(),
// )));
// let backend_runner = Box::new(ShellRunner {
// backend: backend.clone(),
// world: None,
// });
// (backend_runner, backend)
// }
pub struct OrbFontMeasure;
......
......@@ -21,6 +21,7 @@ pub use crate::widgets::*;
pub use dces::prelude::*;
pub use orbtk_css_engine::prelude as css_engine;
pub use orbtk_shell as shell;
pub use orbtk_theme::prelude as theme;
pub use orbtk_utils::prelude as utils;
pub use orbtk_tree::prelude as tree;
......
......@@ -7,10 +7,10 @@ use std::{
use dces::prelude::{Entity, EntityComponentManager, System};
use crate::{backend::Backend, prelude::*};
use crate::{backend::OrbitalBackend, prelude::*};
pub struct EventSystem {
pub backend: Rc<RefCell<dyn Backend>>,
pub backend: Rc<RefCell<OrbitalBackend>>,
pub handlers: Rc<RefCell<BTreeMap<Entity, Vec<Rc<dyn EventHandler>>>>>,
pub update: Rc<Cell<bool>>,
pub running: Rc<Cell<bool>>,
......
......@@ -2,11 +2,11 @@ use std::{cell::RefCell, rc::Rc, collections::BTreeMap};
use dces::prelude::{Entity, EntityComponentManager, System};
use crate::{backend::Backend, prelude::*};
use crate::{backend::OrbitalBackend, prelude::*};
/// This system is used to initializes the widgets.
pub struct InitSystem {
pub backend: Rc<RefCell<dyn Backend>>,
pub backend: Rc<RefCell<OrbitalBackend>>,
pub states: Rc<RefCell<BTreeMap<Entity, Rc<dyn State>>>>,
}
......@@ -56,7 +56,7 @@ impl System<Tree> for InitSystem {
println!("\n------ Widget tree ------\n");
}
// init css ids
for node in tree.into_iter() {
......
......@@ -6,12 +6,12 @@ use std::{
use dces::prelude::{Entity, EntityComponentManager, System};
use crate::{backend::Backend, prelude::*};
use crate::{backend::OrbitalBackend, prelude::*};
/// The `LayoutSystem` builds per iteration the layout of the current ui. The layout parts are calulated by the layout objects of layout widgets.
pub struct LayoutSystem {
pub layouts: Rc<RefCell<BTreeMap<Entity, Box<dyn Layout>>>>,
pub backend: Rc<RefCell<dyn Backend>>,
pub backend: Rc<RefCell<OrbitalBackend>>,
pub update: Rc<Cell<bool>>,
pub running: Rc<Cell<bool>>,
}
......
......@@ -12,7 +12,7 @@ use crate::backend::*;
/// The `RenderSystem` iterates over all visual widgets and used its render objects to draw them on the screen.
pub struct RenderSystem {
pub render_objects: Rc<RefCell<BTreeMap<Entity, Box<dyn RenderObject>>>>,
pub backend: Rc<RefCell<dyn Backend>>,
pub backend: Rc<RefCell<OrbitalBackend>>,
pub update: Rc<Cell<bool>>,
pub running: Rc<Cell<bool>>,
}
......
......@@ -6,11 +6,11 @@ use std::{
use dces::prelude::{Entity, EntityComponentManager, System};
use crate::{backend::Backend, prelude::*};
use crate::{backend::OrbitalBackend, prelude::*};
/// The `StateSystem` calls the update methods of widget states.
pub struct StateSystem {
pub backend: Rc<RefCell<dyn Backend>>,
pub backend: Rc<RefCell<OrbitalBackend>>,
pub states: Rc<RefCell<BTreeMap<Entity, Rc<dyn State>>>>,
pub update: Rc<Cell<bool>>,
pub running: Rc<Cell<bool>>,
......@@ -124,7 +124,7 @@ impl System<Tree> for StateSystem {
/// The `PostLayoutStateSystem` calls the update_post_layout methods of widget states.
pub struct PostLayoutStateSystem {
pub backend: Rc<RefCell<dyn Backend>>,
pub backend: Rc<RefCell<OrbitalBackend>>,
pub states: Rc<RefCell<BTreeMap<Entity, Rc<dyn State>>>>,
pub update: Rc<Cell<bool>>,
pub running: Rc<Cell<bool>>,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment