More macros?
This commit is contained in:
parent
53cb2a22b1
commit
d5fc504821
|
@ -1111,6 +1111,7 @@ dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"lan_party_core",
|
"lan_party_core",
|
||||||
|
"paste",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
|
|
@ -18,3 +18,4 @@ thiserror = "1"
|
||||||
yew-hooks = "0.1"
|
yew-hooks = "0.1"
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
js-sys = "0.3"
|
js-sys = "0.3"
|
||||||
|
paste = "1"
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@6.9.96/css/materialdesignicons.min.css" rel="stylesheet">
|
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@6.9.96/css/materialdesignicons.min.css" rel="stylesheet">
|
||||||
<title>Yew App</title>
|
<title>Yew App</title>
|
||||||
|
|
||||||
<link rel="preload" href="/index-eca47f078afaab22_bg.wasm" as="fetch" type="application/wasm" crossorigin="">
|
<link rel="preload" href="/index-f3d26bdebe032292_bg.wasm" as="fetch" type="application/wasm" crossorigin="">
|
||||||
<link rel="modulepreload" href="/index-eca47f078afaab22.js"></head>
|
<link rel="modulepreload" href="/index-f3d26bdebe032292.js"></head>
|
||||||
<body class="base theme-dark bg-gray-900 text-gray-400">
|
<body class="base theme-dark bg-gray-900 text-gray-400">
|
||||||
|
|
||||||
|
|
||||||
<script type="module">import init from '/index-eca47f078afaab22.js';init('/index-eca47f078afaab22_bg.wasm');</script></body></html>
|
<script type="module">import init from '/index-f3d26bdebe032292.js';init('/index-f3d26bdebe032292_bg.wasm');</script></body></html>
|
|
@ -7,6 +7,7 @@ use lan_party_core::event::{
|
||||||
test::{Test, TestSpec},
|
test::{Test, TestSpec},
|
||||||
*,
|
*,
|
||||||
};
|
};
|
||||||
|
use paste::paste;
|
||||||
use wasm_bindgen::JsValue;
|
use wasm_bindgen::JsValue;
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
|
@ -225,6 +226,61 @@ view_struct!(TeamGame as self =>
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
macro_rules! edit_fields {
|
||||||
|
($(($name:expr, $prop:expr)),* $(,)?) => {
|
||||||
|
html! {
|
||||||
|
<>
|
||||||
|
$(
|
||||||
|
<p>
|
||||||
|
{ $name }
|
||||||
|
{ $prop.edit() }
|
||||||
|
</p>
|
||||||
|
)*
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! link_fields {
|
||||||
|
($($field:ident),* $(,)? => $state:ident as $t:ident) => {
|
||||||
|
$(let $field = use_state(|| $state.$field.clone());)*
|
||||||
|
|
||||||
|
use_effect_with_deps(
|
||||||
|
clone!($($field,)* $state =>
|
||||||
|
move |_| {
|
||||||
|
$state.set($t {
|
||||||
|
$($field: (*$field).clone(),)*
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
|| { $(drop($field);)* drop($state); }
|
||||||
|
}
|
||||||
|
),
|
||||||
|
($($field.clone(),)*),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! edit_struct {
|
||||||
|
($struct:ident => $(($name:expr, $prop:ident)),* $(,)?) => {
|
||||||
|
paste! {
|
||||||
|
#[function_component([<$struct Edit>])]
|
||||||
|
pub fn event_spec_edit(props: &EditProps<$struct>) -> Html {
|
||||||
|
let state = props.state.clone();
|
||||||
|
link_fields!(name, description => state as $struct);
|
||||||
|
html! {
|
||||||
|
<Block title={stringify!($struct)}>
|
||||||
|
{ edit_fields!(("Name: ", name), ("Description: ", description)) }
|
||||||
|
</Block>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Editable for $struct {
|
||||||
|
type Edit = [<$struct Edit>];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Properties)]
|
#[derive(PartialEq, Properties)]
|
||||||
pub struct EditProps<T: PartialEq> {
|
pub struct EditProps<T: PartialEq> {
|
||||||
pub state: UseStateHandle<T>,
|
pub state: UseStateHandle<T>,
|
||||||
|
@ -234,43 +290,20 @@ pub trait Edit {
|
||||||
fn edit(&self) -> Html;
|
fn edit(&self) -> Html;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[function_component(EventSpecEdit)]
|
impl<Comp: Component<Properties = EditProps<Type>>, Type: Editable<Edit = Comp> + PartialEq> Edit
|
||||||
pub fn event_spec_edit(props: &EditProps<EventSpec>) -> Html {
|
for UseStateHandle<Type>
|
||||||
let state = props.state.clone();
|
{
|
||||||
let name = use_state(|| state.name.clone());
|
|
||||||
let description = use_state(|| state.description.clone());
|
|
||||||
|
|
||||||
use_effect_with_deps(
|
|
||||||
clone!(name, description, state =>
|
|
||||||
move |_| {
|
|
||||||
web_sys::console::log_1(&JsValue::from("Update EventSpec"));
|
|
||||||
state.set(EventSpec {
|
|
||||||
name: (*name).clone(),
|
|
||||||
description: (*description).clone(),
|
|
||||||
..Default::default()
|
|
||||||
});
|
|
||||||
|| { drop(state); drop(name); drop(description) }
|
|
||||||
}
|
|
||||||
),
|
|
||||||
(name.clone(), description.clone()),
|
|
||||||
);
|
|
||||||
|
|
||||||
html! {
|
|
||||||
<>
|
|
||||||
{ "Name: " }
|
|
||||||
{ name.edit() }
|
|
||||||
{ "Description: " }
|
|
||||||
{ description.edit() }
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Edit for UseStateHandle<EventSpec> {
|
|
||||||
fn edit(&self) -> Html {
|
fn edit(&self) -> Html {
|
||||||
html!(<EventSpecEdit state={self.clone()} />)
|
html!(<Comp state={self.clone()} />)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait Editable {
|
||||||
|
type Edit;
|
||||||
|
}
|
||||||
|
|
||||||
|
edit_struct!(EventSpec => ("Name: ", name), ("Description: ", description));
|
||||||
|
|
||||||
#[function_component(StringEdit)]
|
#[function_component(StringEdit)]
|
||||||
pub fn string_edit(props: &EditProps<String>) -> Html {
|
pub fn string_edit(props: &EditProps<String>) -> Html {
|
||||||
let string = props.state.clone();
|
let string = props.state.clone();
|
||||||
|
@ -288,73 +321,3 @@ impl Edit for UseStateHandle<String> {
|
||||||
html!(<StringEdit state={self.clone()} />)
|
html!(<StringEdit state={self.clone()} />)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
pub trait Edit {
|
|
||||||
type Type;
|
|
||||||
|
|
||||||
fn to_edit(t: Self::Type) -> Self;
|
|
||||||
fn edit(&self) -> Html;
|
|
||||||
fn build(&self) -> Self::Type;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct EventSpecEditHandle {
|
|
||||||
name: UseStateHandle<String>,
|
|
||||||
description: UseStateHandle<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Edit for UseStateHandle<String> {
|
|
||||||
type Type = String;
|
|
||||||
|
|
||||||
fn to_edit(t: Self::Type) -> Self {
|
|
||||||
use_state(|| t)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn edit(&self) -> Html {
|
|
||||||
let this = self.clone();
|
|
||||||
|
|
||||||
html! {
|
|
||||||
<TextInput
|
|
||||||
class={"mx-2 appearance-none block bg-gray-700 text-slate-400 border border-gray-600 rounded py-2 px-2 w-20 leading-tight focus:outline-none focus:ring-1 focus:ring-gray-500 focus:border-gray-500"}
|
|
||||||
bind={bind!(this)}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build(&self) -> Self::Type {
|
|
||||||
(*self.clone()).clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Edit for EventSpecEditHandle {
|
|
||||||
type Type = EventSpec;
|
|
||||||
|
|
||||||
fn to_edit(t: Self::Type) -> Self {
|
|
||||||
Self {
|
|
||||||
name: use_state(|| t.name),
|
|
||||||
description: use_state(|| t.description),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn edit(&self) -> Html {
|
|
||||||
html! {
|
|
||||||
<>
|
|
||||||
{ "Name: " }
|
|
||||||
{ self.name.edit() }
|
|
||||||
{ "Description: " }
|
|
||||||
{ self.description.edit() }
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build(&self) -> Self::Type {
|
|
||||||
let test_spec = TestSpec { num_players: 0 };
|
|
||||||
|
|
||||||
Self::Type {
|
|
||||||
name: self.name.build(),
|
|
||||||
description: self.description.build(),
|
|
||||||
event_type: EventTypeSpec::Test(test_spec),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
Loading…
Reference in New Issue