Compare commits
2 commits
86be46a050
...
492d57b856
Author | SHA1 | Date | |
---|---|---|---|
492d57b856 | |||
b0a9d66db3 |
13 changed files with 170 additions and 77 deletions
|
@ -5,17 +5,20 @@ authors = ["hodasemi <michaelh.95@t-online.de>"]
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
quick-xml = "0.31.0"
|
quick-xml = "0.37.0"
|
||||||
serde = { version = "1.0.203", features = ["derive"] }
|
serde = { version = "1.0.203", features = ["derive"] }
|
||||||
serde_json = { version = "1.0.120" }
|
serde_json = { version = "1.0.120" }
|
||||||
paste = "1.0.15"
|
paste = "1.0.15"
|
||||||
anyhow = { version = "1.0.86", features = ["backtrace"] }
|
anyhow = { version = "1.0.86", features = ["backtrace"] }
|
||||||
|
itertools = "0.14.0"
|
||||||
|
|
||||||
vulkan-rs = { git = "https://gavania.de/hodasemi/vulkan_lib.git" }
|
vulkan-rs = { git = "https://gavania.de/hodasemi/vulkan_lib.git" }
|
||||||
utilities = { git = "https://gavania.de/hodasemi/utilities.git" }
|
utilities = { git = "https://gavania.de/hodasemi/utilities.git" }
|
||||||
assetpath = { git = "https://gavania.de/hodasemi/vulkan_lib.git" }
|
assetpath = { git = "https://gavania.de/hodasemi/vulkan_lib.git" }
|
||||||
ecs = { git = "https://gavania.de/hodasemi/ecs.git" }
|
ecs = { git = "https://gavania.de/hodasemi/ecs.git" }
|
||||||
|
|
||||||
|
ui_proc_macro = { path = "../ui_proc_macro" }
|
||||||
|
|
||||||
# optional
|
# optional
|
||||||
audio = { git = "https://gavania.de/hodasemi/audio.git", optional = true }
|
audio = { git = "https://gavania.de/hodasemi/audio.git", optional = true }
|
||||||
|
|
||||||
|
|
|
@ -203,7 +203,8 @@ impl Functionality for GuiBuilder {
|
||||||
let suffix_less_function_name = handle_function_suffix(function_name);
|
let suffix_less_function_name = handle_function_suffix(function_name);
|
||||||
|
|
||||||
let button: Arc<Button> = self.element(&suffix_less_function_name)?;
|
let button: Arc<Button> = self.element(&suffix_less_function_name)?;
|
||||||
button.set_callback(callback);
|
todo!()
|
||||||
|
// button.set_callback(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -181,7 +181,8 @@ impl Functionality for GuiSnippet {
|
||||||
let suffix_less_function_name = handle_function_suffix(function_name);
|
let suffix_less_function_name = handle_function_suffix(function_name);
|
||||||
|
|
||||||
let button: Arc<Button> = self.element(&suffix_less_function_name)?;
|
let button: Arc<Button> = self.element(&suffix_less_function_name)?;
|
||||||
button.set_callback(callback);
|
todo!()
|
||||||
|
// button.set_callback(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -271,9 +271,9 @@ pub struct Button {
|
||||||
#[cfg(feature = "audio")]
|
#[cfg(feature = "audio")]
|
||||||
_hover_sound: Option<Arc<Audible>>,
|
_hover_sound: Option<Arc<Audible>>,
|
||||||
|
|
||||||
click_executable: Arc<Executable<()>>,
|
pub(crate) click_executable: Arc<Executable<()>>,
|
||||||
select_executable: Arc<Executable<bool>>,
|
pub(crate) select_executable: Arc<Executable<bool>>,
|
||||||
on_select_executable: Arc<Executable<bool>>,
|
pub(crate) on_select_executable: Arc<Executable<bool>>,
|
||||||
|
|
||||||
normal: FillType,
|
normal: FillType,
|
||||||
selected: FillType,
|
selected: FillType,
|
||||||
|
@ -313,26 +313,23 @@ impl Button {
|
||||||
self.selectable.select(gui_handler)
|
self.selectable.select(gui_handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_callback<F>(&self, callback: F)
|
// pub fn set_callback<F>(&self, callback: F)
|
||||||
where
|
// where
|
||||||
F: Fn(&mut Commands, &mut GuiHandler) -> Result<()> + Send + Sync + 'static,
|
// F: Fn(&mut Commands, &mut GuiHandler) -> Result<()> + Send + Sync + 'static,
|
||||||
{
|
// {
|
||||||
self.click_executable.set_callback(
|
// self.click_executable.set_callback(
|
||||||
move |commands: &mut Commands, gui_handler: &mut GuiHandler, _: ()| {
|
// move |commands: &mut Commands, gui_handler: &mut GuiHandler, _: ()| {
|
||||||
callback(commands, gui_handler)
|
// callback(commands, gui_handler)
|
||||||
},
|
// },
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn set_select_callback<F>(&self, callback: F)
|
pub fn set_select_callback<F>(&self, callback: F)
|
||||||
where
|
where
|
||||||
F: Fn(&mut Commands, &mut GuiHandler, bool) -> Result<()> + Send + Sync + 'static,
|
F: Fn(&mut Commands, &mut GuiHandler, bool) -> Result<()> + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
self.on_select_executable.set_callback(
|
todo!()
|
||||||
move |commands: &mut Commands, gui_handler: &mut GuiHandler, select: bool| {
|
// self.on_select_executable.set_callback(callback);
|
||||||
callback(commands, gui_handler, select)
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_custom_callback<F>(&self, callback: F)
|
pub fn set_custom_callback<F>(&self, callback: F)
|
||||||
|
@ -593,18 +590,20 @@ impl Button {
|
||||||
fn create_selected_changed_callback(button: Arc<Button>) {
|
fn create_selected_changed_callback(button: Arc<Button>) {
|
||||||
let button_weak = Arc::downgrade(&button);
|
let button_weak = Arc::downgrade(&button);
|
||||||
|
|
||||||
let selected_changed =
|
let selected_changed = move |_world: &mut World,
|
||||||
move |_commands: &mut Commands, gui_handler: &mut GuiHandler, selected: bool| {
|
_commands: &mut Commands,
|
||||||
if let Some(button) = button_weak.upgrade() {
|
gui_handler: &mut GuiHandler,
|
||||||
if selected {
|
selected: bool| {
|
||||||
button.set_button_state(gui_handler, ButtonState::Selected)?;
|
if let Some(button) = button_weak.upgrade() {
|
||||||
} else {
|
if selected {
|
||||||
button.set_button_state(gui_handler, ButtonState::Normal)?;
|
button.set_button_state(gui_handler, ButtonState::Selected)?;
|
||||||
}
|
} else {
|
||||||
|
button.set_button_state(gui_handler, ButtonState::Normal)?;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
};
|
};
|
||||||
|
|
||||||
button.select_executable.set_callback(selected_changed);
|
button.select_executable.set_callback(selected_changed);
|
||||||
}
|
}
|
||||||
|
|
22
ui/src/elements/callback_impl.rs
Normal file
22
ui/src/elements/callback_impl.rs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
use anyhow::Result;
|
||||||
|
use ecs::{resources::Resource as ResourceTrait, *};
|
||||||
|
use itertools::Itertools;
|
||||||
|
use ui_proc_macro::implement_callbacks;
|
||||||
|
|
||||||
|
use crate::prelude::*;
|
||||||
|
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
pub trait SetCallback<T, R, Func, Filter> {
|
||||||
|
fn set_callback(&self, func: Func);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait SetSelectCallback<T, R, Func, Filter> {
|
||||||
|
fn set_select_callback(&self, func: Func);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait SetCustomCallback<T, R, Func, Filter> {
|
||||||
|
fn set_custom_callback(&self, func: Func);
|
||||||
|
}
|
||||||
|
|
||||||
|
implement_callbacks!(2, 0);
|
|
@ -18,6 +18,7 @@ pub mod ui_element;
|
||||||
pub mod traits;
|
pub mod traits;
|
||||||
|
|
||||||
mod callback_builder;
|
mod callback_builder;
|
||||||
|
pub mod callback_impl;
|
||||||
pub mod prelude;
|
pub mod prelude;
|
||||||
mod wrapper;
|
mod wrapper;
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,10 @@ impl MultiLineTextFieldBuilder {
|
||||||
multi_line_text_field.text_changed_exec.set_callback({
|
multi_line_text_field.text_changed_exec.set_callback({
|
||||||
let weak_tf = Arc::downgrade(&multi_line_text_field);
|
let weak_tf = Arc::downgrade(&multi_line_text_field);
|
||||||
|
|
||||||
move |_commands: &mut Commands, gui_handler: &mut GuiHandler, _text| {
|
move |_world: &mut World,
|
||||||
|
_commands: &mut Commands,
|
||||||
|
gui_handler: &mut GuiHandler,
|
||||||
|
_text| {
|
||||||
if let Some(tf) = weak_tf.upgrade() {
|
if let Some(tf) = weak_tf.upgrade() {
|
||||||
tf.update_text(gui_handler)?;
|
tf.update_text(gui_handler)?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -172,7 +172,8 @@ impl TextField {
|
||||||
where
|
where
|
||||||
F: Fn(&mut Commands, &mut GuiHandler, Option<String>) -> Result<()> + Send + Sync + 'static,
|
F: Fn(&mut Commands, &mut GuiHandler, Option<String>) -> Result<()> + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
self.text_changed_executable.set_callback(f);
|
todo!()
|
||||||
|
// self.text_changed_executable.set_callback(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_text_color(&self, gui_handler: &mut GuiHandler, text_color: Color) -> Result<()> {
|
pub fn set_text_color(&self, gui_handler: &mut GuiHandler, text_color: Color) -> Result<()> {
|
||||||
|
|
|
@ -9,8 +9,11 @@ use crate::prelude::*;
|
||||||
|
|
||||||
/// `Executable` holds a closure which can be executed
|
/// `Executable` holds a closure which can be executed
|
||||||
pub struct Executable<I: Send + Sync> {
|
pub struct Executable<I: Send + Sync> {
|
||||||
callback:
|
callback: RwLock<
|
||||||
RwLock<Option<Arc<dyn Fn(&mut Commands, &mut GuiHandler, I) -> Result<()> + Send + Sync>>>,
|
Option<
|
||||||
|
Arc<dyn Fn(&mut World, &mut Commands, &mut GuiHandler, I) -> Result<()> + Send + Sync>,
|
||||||
|
>,
|
||||||
|
>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I: Send + Sync + 'static> Executable<I> {
|
impl<I: Send + Sync + 'static> Executable<I> {
|
||||||
|
@ -28,7 +31,7 @@ impl<I: Send + Sync + 'static> Executable<I> {
|
||||||
/// * `callback` is a `Option<Callback>` closure
|
/// * `callback` is a `Option<Callback>` closure
|
||||||
pub fn set_callback<F>(&self, callback: impl Into<Option<F>>)
|
pub fn set_callback<F>(&self, callback: impl Into<Option<F>>)
|
||||||
where
|
where
|
||||||
F: Fn(&mut Commands, &mut GuiHandler, I) -> Result<()> + Send + Sync + 'static,
|
F: Fn(&mut World, &mut Commands, &mut GuiHandler, I) -> Result<()> + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
let mut function = self.callback.write().unwrap();
|
let mut function = self.callback.write().unwrap();
|
||||||
|
|
||||||
|
@ -43,8 +46,8 @@ impl<I: Send + Sync + 'static> Executable<I> {
|
||||||
if let Some(callback) = self.callback.read().unwrap().as_ref() {
|
if let Some(callback) = self.callback.read().unwrap().as_ref() {
|
||||||
let callback = callback.clone();
|
let callback = callback.clone();
|
||||||
|
|
||||||
gui_handler.add_callback(move |commands, gui_handler| {
|
gui_handler.add_callback(move |world, commands, gui_handler| {
|
||||||
(callback)(commands, gui_handler, input)
|
(callback)(world, commands, gui_handler, input)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -245,7 +245,9 @@ pub struct GuiHandler {
|
||||||
|
|
||||||
text_sample_count: VkSampleCountFlags,
|
text_sample_count: VkSampleCountFlags,
|
||||||
|
|
||||||
callback_list: Vec<Box<dyn FnOnce(&mut Commands, &mut GuiHandler) -> Result<()> + Send + Sync>>,
|
callback_list: Vec<
|
||||||
|
Box<dyn FnOnce(&mut World, &mut Commands, &mut GuiHandler) -> Result<()> + Send + Sync>,
|
||||||
|
>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GuiHandler {
|
impl GuiHandler {
|
||||||
|
@ -927,7 +929,7 @@ impl GuiHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn add_callback<
|
pub(crate) fn add_callback<
|
||||||
F: FnOnce(&mut Commands, &mut GuiHandler) -> Result<()> + Send + Sync + 'static,
|
F: FnOnce(&mut World, &mut Commands, &mut GuiHandler) -> Result<()> + Send + Sync + 'static,
|
||||||
>(
|
>(
|
||||||
&mut self,
|
&mut self,
|
||||||
f: F,
|
f: F,
|
||||||
|
@ -935,12 +937,17 @@ impl GuiHandler {
|
||||||
self.callback_list.push(Box::new(f));
|
self.callback_list.push(Box::new(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn process_callbacks(&mut self, commands: &mut Commands) -> Result<()> {
|
pub fn process_callbacks(&mut self, world: &mut World) -> Result<()> {
|
||||||
let callbacks = mem::take(&mut self.callback_list);
|
let callbacks = mem::take(&mut self.callback_list);
|
||||||
|
let mut commands = Commands::new(world.now());
|
||||||
|
|
||||||
callbacks
|
callbacks
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.try_for_each(|callback| callback(commands, self))
|
.try_for_each(|callback| callback(world, &mut commands, self))?;
|
||||||
|
|
||||||
|
commands.apply_deferred(world);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(
|
fn render(
|
||||||
|
|
|
@ -376,19 +376,20 @@ impl Keyboard {
|
||||||
let weak_textfield = Arc::downgrade(&textfield);
|
let weak_textfield = Arc::downgrade(&textfield);
|
||||||
let weak_button = Arc::downgrade(&button_ref);
|
let weak_button = Arc::downgrade(&button_ref);
|
||||||
|
|
||||||
button_ref.set_callback(Box::new(
|
todo!();
|
||||||
move |_commands: &mut Commands, gui_handler: &mut GuiHandler| {
|
// button_ref.set_callback(Box::new(
|
||||||
if let Some(textfield) = weak_textfield.upgrade() {
|
// move |_world: &mut World, _commands: &mut Commands, gui_handler: &mut GuiHandler| {
|
||||||
if let Some(button) = weak_button.upgrade() {
|
// if let Some(textfield) = weak_textfield.upgrade() {
|
||||||
if let Some(text) = button.text()? {
|
// if let Some(button) = weak_button.upgrade() {
|
||||||
textfield.add_letter(gui_handler, text.as_bytes()[0] as char)?;
|
// if let Some(text) = button.text()? {
|
||||||
}
|
// textfield.add_letter(gui_handler, text.as_bytes()[0] as char)?;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
Ok(())
|
// Ok(())
|
||||||
},
|
// },
|
||||||
));
|
// ));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,8 @@ mod update;
|
||||||
use update::update;
|
use update::update;
|
||||||
|
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
use quote::quote;
|
|
||||||
use syn::{
|
use syn::{
|
||||||
DeriveInput, LitInt, Result,
|
LitInt, Result,
|
||||||
parse::{Parse, ParseStream},
|
parse::{Parse, ParseStream},
|
||||||
parse_macro_input,
|
parse_macro_input,
|
||||||
token::Comma,
|
token::Comma,
|
||||||
|
@ -30,7 +29,7 @@ impl Parse for UpdateInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[proc_macro]
|
#[proc_macro]
|
||||||
pub fn implement_updates(input: TokenStream) -> TokenStream {
|
pub fn implement_callbacks(input: TokenStream) -> TokenStream {
|
||||||
let input = parse_macro_input!(input as UpdateInfo);
|
let input = parse_macro_input!(input as UpdateInfo);
|
||||||
|
|
||||||
update(input.max_components, input.max_resources)
|
update(input.max_components, input.max_resources)
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
use proc_macro::TokenStream;
|
||||||
use proc_macro2::TokenStream as TokenStream2;
|
use proc_macro2::TokenStream as TokenStream2;
|
||||||
|
use quote::quote;
|
||||||
use update_macro_base::*;
|
use update_macro_base::*;
|
||||||
|
|
||||||
fn resource_only_events_and_systems(update: &Update) -> TokenStream2 {
|
fn resource_only_events_and_systems(update: &Update) -> TokenStream2 {
|
||||||
|
@ -11,7 +13,7 @@ fn resource_only_events_and_systems(update: &Update) -> TokenStream2 {
|
||||||
let resource_store = &resource_tokens.resource_store;
|
let resource_store = &resource_tokens.resource_store;
|
||||||
let resource_idents = &resource_tokens.resource_idents;
|
let resource_idents = &resource_tokens.resource_idents;
|
||||||
|
|
||||||
todo!()
|
quote! {}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn events_and_systems(update: &Update) -> TokenStream2 {
|
fn events_and_systems(update: &Update) -> TokenStream2 {
|
||||||
|
@ -40,29 +42,77 @@ fn events_and_systems(update: &Update) -> TokenStream2 {
|
||||||
let resource_store = &resource_tokens.resource_store;
|
let resource_store = &resource_tokens.resource_store;
|
||||||
let resource_idents = &resource_tokens.resource_idents;
|
let resource_idents = &resource_tokens.resource_idents;
|
||||||
|
|
||||||
todo!()
|
quote! {
|
||||||
|
impl<Func, #filter_type_impls #query_type_impls #resource_type_impls> SetCallback<#query_types, #resource_types, Func, #filter_types> for Button
|
||||||
|
where
|
||||||
|
Func: Fn(&mut Commands, &mut GuiHandler, #( #queries, )* #resources ) -> Result<()> + Send + Sync + 'static,
|
||||||
|
#filter_requirements
|
||||||
|
#component_requirements
|
||||||
|
#resource_requirement
|
||||||
|
{
|
||||||
|
fn set_callback(&self, func: Func) {
|
||||||
|
#( #verify_dedup )*
|
||||||
|
|
||||||
|
self.click_executable.set_callback(
|
||||||
|
move |world: &mut World, commands: &mut Commands, gui_handler: &mut GuiHandler, _: ()| -> Result<()> {
|
||||||
|
let mut complying_entities: Vec<Vec<&EntityObject>> = vec![Vec::new(); #query_count];
|
||||||
|
|
||||||
|
for entity in unsafe { utilities::prelude::remove_life_time(world).entities() } {
|
||||||
|
let mut comply_queries = Vec::new();
|
||||||
|
|
||||||
|
#( #check_entities )*
|
||||||
|
|
||||||
|
if !comply_queries.is_empty() {
|
||||||
|
comply_queries
|
||||||
|
.into_iter()
|
||||||
|
.for_each(|q| complying_entities[q].push(entity));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if one of the queries could not be fullfilled
|
||||||
|
for queryable_entities in complying_entities.iter() {
|
||||||
|
if queryable_entities.is_empty() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#resource_store
|
||||||
|
|
||||||
|
for entities in complying_entities.into_iter().multi_cartesian_product() {
|
||||||
|
#( #component_stores )*
|
||||||
|
#( #query_structs )*
|
||||||
|
|
||||||
|
func(commands, gui_handler, #( #query_idents, )* #( #resource_idents, )*)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(max_components: usize, max_resources: usize) -> TokenStream2 {
|
pub fn update(max_components: usize, max_resources: usize) -> TokenStream {
|
||||||
let mut queries: Vec<Vec<usize>> = Vec::new();
|
let mut queries: Vec<Vec<usize>> = Vec::new();
|
||||||
|
|
||||||
for c in Update::MIN_COMPONENTS..=max_components {
|
for c in Update::MIN_COMPONENTS..=max_components {
|
||||||
queries.push(vec![c]);
|
queries.push(vec![c]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for x in Update::MIN_COMPONENTS..=max_components {
|
// for x in Update::MIN_COMPONENTS..=max_components {
|
||||||
for y in Update::MIN_COMPONENTS..=max_components {
|
// for y in Update::MIN_COMPONENTS..=max_components {
|
||||||
queries.push(vec![x, y]);
|
// queries.push(vec![x, y]);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
for x in Update::MIN_COMPONENTS..=max_components {
|
// for x in Update::MIN_COMPONENTS..=max_components {
|
||||||
for y in Update::MIN_COMPONENTS..=max_components {
|
// for y in Update::MIN_COMPONENTS..=max_components {
|
||||||
for z in Update::MIN_COMPONENTS..=max_components {
|
// for z in Update::MIN_COMPONENTS..=max_components {
|
||||||
queries.push(vec![x, y, z]);
|
// queries.push(vec![x, y, z]);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
let mut resources = Vec::new();
|
let mut resources = Vec::new();
|
||||||
|
|
||||||
|
@ -90,16 +140,18 @@ fn update(max_components: usize, max_resources: usize) -> TokenStream2 {
|
||||||
events.push(q);
|
events.push(q);
|
||||||
}
|
}
|
||||||
|
|
||||||
// updates.push(Update::new(vec![1].into_iter(), 0));
|
// updates.push(events_and_systems(&Update::new(vec![2].into_iter(), 0)));
|
||||||
|
|
||||||
// let q = quote! {
|
// let q = quote! {
|
||||||
// #( #updates )*
|
// #( #updates )*
|
||||||
// };
|
// };
|
||||||
|
|
||||||
// panic!("{q}");
|
let q = quote! {
|
||||||
|
|
||||||
TokenStream::from(quote! {
|
|
||||||
#( #updates )*
|
#( #updates )*
|
||||||
#( #events )*
|
#( #events )*
|
||||||
})
|
};
|
||||||
|
|
||||||
|
panic!("{q}");
|
||||||
|
|
||||||
|
TokenStream::from(q)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue