feat: got a minimal prototype of the diffing system
This commit is contained in:
@@ -321,10 +321,9 @@ impl<B: DisplayBackend> App<B> {
|
||||
|
||||
let initiator = WindowInitiator::new(&window_def, window_args)?;
|
||||
|
||||
// Holds the id and the props of a widget
|
||||
// It is crutual for supporting dynamic updates
|
||||
// Should hold the id and the props of a widget
|
||||
// It is critical for supporting dynamic updates
|
||||
let mut widget_reg_store = WidgetRegistry::new();
|
||||
// note for future me: ^ this might need cloning.
|
||||
|
||||
let root_widget = build_gtk_widget(WidgetInput::Window(window_def), &mut widget_reg_store)?;
|
||||
|
||||
|
||||
@@ -24,6 +24,14 @@ pub fn build_gtk_widget(input: WidgetInput, widget_reg: &mut WidgetRegistry) ->
|
||||
// TODO: implement the commented lines
|
||||
fn build_gtk_widget_from_node(root_node: WidgetNode, widget_reg: &mut WidgetRegistry) -> Result<gtk::Widget> {
|
||||
let root_node2 = root_node.clone();
|
||||
|
||||
/*
|
||||
When a a new widget is added to the build process,
|
||||
make sure to update get_id_to_props_map() found in
|
||||
`iirhai/widgetnode.rs`. It is crutial to presrve
|
||||
dynamic update system in ewwii.
|
||||
*/
|
||||
|
||||
let gtk_widget = match root_node {
|
||||
WidgetNode::Box { props, children } => build_gtk_box(props, children, widget_reg)?.upcast(),
|
||||
WidgetNode::CenterBox { props, children } => build_center_box(props, children, widget_reg)?.upcast(),
|
||||
|
||||
@@ -59,6 +59,13 @@ pub struct WidgetEntry {
|
||||
|
||||
pub struct WidgetRegistry {
|
||||
widgets: HashMap<u64, WidgetEntry>,
|
||||
stored_widget_node: Option<WidgetNode>,
|
||||
}
|
||||
|
||||
pub enum PatchGtkWidget {
|
||||
Create(u64, Map),
|
||||
Update(u64, Map),
|
||||
Remove(u64),
|
||||
}
|
||||
|
||||
impl WidgetRegistry {
|
||||
@@ -66,7 +73,28 @@ impl WidgetRegistry {
|
||||
Self { widgets: HashMap::new() }
|
||||
}
|
||||
|
||||
pub fn update_prop_changes(&self, id_to_props: HashMap<u64, Map>) {
|
||||
fn diff_trees(old: Option<WidgetNode>, new: WidgetNode) -> Vec<PatchGtkWidget> {
|
||||
let mut id_to_prop = HashMap::new();
|
||||
let _ = get_id_to_props_map(&new_widget, &mut id_to_prop);
|
||||
}
|
||||
|
||||
pub fn update_widget_tree(&mut self, new_tree: WidgetNode) {
|
||||
let old_tree = self.stored_widget_node.take();
|
||||
|
||||
let patch = diff_trees(old_tree, new_tree.clone());
|
||||
|
||||
for op in patch {
|
||||
match op {
|
||||
PatchGtkWidget::Create(widget_id, props) => self.create_widget(widget_id, props),
|
||||
PatchGtkWidget::Update(widget_id, new_props) => self.update_props(widget_id, new_props),
|
||||
PatchGtkWidget::Remove(widget_id) => self.remove_widget(widget_id),
|
||||
}
|
||||
}
|
||||
|
||||
self.stored_widget_node = Some(new_tree);
|
||||
}
|
||||
|
||||
pub fn update_props(&self, id_to_props: HashMap<u64, Map>) {
|
||||
for (id, props) in id_to_props {
|
||||
if let Some(entry) = self.widgets.get(&id) {
|
||||
(entry.update_fn)(&props);
|
||||
|
||||
@@ -39,7 +39,14 @@ pub enum WidgetNode {
|
||||
Enter(Vec<WidgetNode>),
|
||||
}
|
||||
|
||||
pub fn get_id_to_props_map(root_node: &WidgetNode, id_to_props: &mut HashMap<u64, Map>) -> Result<()> {
|
||||
// Get `HashMap<widget_id, widget_prop>`
|
||||
// not exactly a get function as it mutates id_to_props
|
||||
// instead of returning any value.
|
||||
// it sounds misleading but i cant think of a better name.
|
||||
pub fn get_id_to_props_map(
|
||||
root_node: &WidgetNode,
|
||||
id_to_props: &mut HashMap<u64, Map>
|
||||
) -> Result<()> {
|
||||
match root_node {
|
||||
WidgetNode::Box { props, children } => {
|
||||
insert_props(props, "Box", id_to_props)?;
|
||||
|
||||
Reference in New Issue
Block a user