Some more woogaloo around action dispatch

Co-authored-by: Conrad <conrad@zed.dev>
This commit is contained in:
Piotr Osiewicz 2023-11-09 18:51:37 +01:00
parent 194d615691
commit a1d9f351db
3 changed files with 54 additions and 10 deletions

View file

@ -33,6 +33,9 @@ pub fn init(cx: &mut AppContext) {
return None;
};
let available_actions = cx.available_actions();
dbg!(&available_actions);
Some(cx.build_view(|cx| {
let delegate =
CommandPaletteDelegate::new(cx.view().downgrade(), focus_handle);

View file

@ -114,6 +114,7 @@ lazy_static! {
#[derive(Default)]
struct ActionRegistry {
builders_by_name: HashMap<SharedString, ActionBuilder>,
builders_by_type_id: HashMap<TypeId, ActionBuilder>,
all_names: Vec<SharedString>, // So we can return a static slice.
}
@ -122,9 +123,22 @@ pub fn register_action<A: Action>() {
let name = A::qualified_name();
let mut lock = ACTION_REGISTRY.write();
lock.builders_by_name.insert(name.clone(), A::build);
lock.builders_by_type_id.insert(TypeId::of::<A>(), A::build);
lock.all_names.push(name);
}
/// Construct an action based on its name and optional JSON parameters sourced from the keymap.
pub fn build_action_from_type(type_id: &TypeId) -> Result<Box<dyn Action>> {
let lock = ACTION_REGISTRY.read();
let build_action = lock
.builders_by_type_id
.get(type_id)
.ok_or_else(|| anyhow!("no action type registered for {:?}", type_id))?;
(build_action)(None)
}
/// Construct an action based on its name and optional JSON parameters sourced from the keymap.
pub fn build_action(name: &str, params: Option<serde_json::Value>) -> Result<Box<dyn Action>> {
let lock = ACTION_REGISTRY.read();

View file

@ -1,14 +1,15 @@
use crate::{
px, size, Action, AnyBox, AnyDrag, AnyView, AppContext, AsyncWindowContext, AvailableSpace,
Bounds, BoxShadow, Context, Corners, CursorStyle, DevicePixels, DispatchContext, DisplayId,
Edges, Effect, Entity, EntityId, EventEmitter, FileDropEvent, FocusEvent, FontId,
GlobalElementId, GlyphId, Hsla, ImageData, InputEvent, IsZero, KeyListener, KeyMatch,
KeyMatcher, Keystroke, LayoutId, Model, ModelContext, Modifiers, MonochromeSprite, MouseButton,
MouseDownEvent, MouseMoveEvent, MouseUpEvent, Path, Pixels, PlatformAtlas, PlatformDisplay,
PlatformInputHandler, PlatformWindow, Point, PolychromeSprite, PromptLevel, Quad, Render,
RenderGlyphParams, RenderImageParams, RenderSvgParams, ScaledPixels, SceneBuilder, Shadow,
SharedString, Size, Style, SubscriberSet, Subscription, TaffyLayoutEngine, Task, Underline,
UnderlineStyle, View, VisualContext, WeakView, WindowBounds, WindowOptions, SUBPIXEL_VARIANTS,
build_action_from_type, px, size, Action, AnyBox, AnyDrag, AnyView, AppContext,
AsyncWindowContext, AvailableSpace, Bounds, BoxShadow, Context, Corners, CursorStyle,
DevicePixels, DispatchContext, DisplayId, Edges, Effect, Entity, EntityId, EventEmitter,
FileDropEvent, FocusEvent, FontId, GlobalElementId, GlyphId, Hsla, ImageData, InputEvent,
IsZero, KeyListener, KeyMatch, KeyMatcher, Keystroke, LayoutId, Model, ModelContext, Modifiers,
MonochromeSprite, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Path, Pixels,
PlatformAtlas, PlatformDisplay, PlatformInputHandler, PlatformWindow, Point, PolychromeSprite,
PromptLevel, Quad, Render, RenderGlyphParams, RenderImageParams, RenderSvgParams, ScaledPixels,
SceneBuilder, Shadow, SharedString, Size, Style, SubscriberSet, Subscription,
TaffyLayoutEngine, Task, Underline, UnderlineStyle, View, VisualContext, WeakView,
WindowBounds, WindowOptions, SUBPIXEL_VARIANTS,
};
use anyhow::{anyhow, Result};
use collections::HashMap;
@ -1295,6 +1296,32 @@ impl<'a> WindowContext<'a> {
self.window.platform_window.prompt(level, msg, answers)
}
pub fn available_actions(&mut self) -> Vec<Box<dyn Action>> {
let key_dispatch_stack = &self.window.current_frame.key_dispatch_stack;
let mut actions = Vec::new();
dbg!(key_dispatch_stack.len());
for frame in key_dispatch_stack {
match frame {
// todo!factor out a KeyDispatchStackFrame::Action
KeyDispatchStackFrame::Listener {
event_type,
listener: _,
} => {
match build_action_from_type(event_type) {
Ok(action) => {
actions.push(action);
}
Err(err) => {
dbg!(err);
} // we'll hit his if TypeId == KeyDown
}
}
KeyDispatchStackFrame::Context(_) => {}
}
}
actions
}
fn dispatch_action(
&mut self,
action: Box<dyn Action>,