Closed michaelcuneo closed 4 years ago
Hi @michaelcuneo,
Okay - this is an interesting scenario..
The engine comes with a simple messaging channel, which at a high level looks like:
const System1 = (entities, { dispatch, events }) => {
if (events.length)
console.log(events) //-- MessageFromHUD
dispatch({ type: "MessagFromSystem1"})
};
class MyGame extends React.Componet {
onMessageFromGameEngine = e => {
console.log(e); //-- MessagFromSystem1
};
onMessageFromHUD = e => {
this.refs.gameEngine.dispatch({ type: "MessageFromHUD" });
};
render() {
return (
<View>
<GameEngine ref={"gameEngine"} onEvent={onMessageFromGameEngine} systems={[System1]} />
<MyHud onChange={onMessageFromHUD} />
</View>
);
}
}
NOTE: The messages are schema less, you can dispatch whatever data you want.
Perhaps that might simplify things a bit for you? Ideally, I'd like people to be able to focus on their game or interactive scene without writing tonnes of boilerplate redux/saga/flux code..
Just thinking out loud.. Perhaps I can update the engine to automatically make the dispatch
function available to the renderers? That way you can use the dispatch
function in your event handler callbacks? Actually, we can probably achieve this now without an engine update:
const SwitchHUD = (entities, args) => {
const { switchHud } = entities;
if (switchHud) {
switchHud.gamepadController = args.gamepadController;
switchHud.keyController = args.keyController;
switchHud.mouseController = args.mouseController;
switchHud.dispatch = args.dispatch;
}
return entities;
};
export default SwitchHUD;
class SwitchHUDRenderer extends React.Component {
constructor(props) {
super(props);
}
render() {
return [
<Desktop key="Desktop">
<div style={css.desktopHud}>
<h1>
<Text fontSize={['10px', '14px', '20px']}>
<span>
RESIZE
<InputSwitch
checked={props.value}
onChange={e => props.dispatch({ type: "resize", value: !props.value })}
/>
MOVE
</span>
</Text>
</h1>
<h1>
<Text fontSize={['10px', '14px', '20px']}>
<span>
<Button
label="RESET"
className="p-button-danger"
onChange={e => props.dispatch({ type: "reset" })}
/>
</span>
</Text>
</h1>
<h1>
<Text fontSize={['10px', '14px', '20px']}>
<span>
<Button
label="SUBMIT"
className="p-button-standard"
onChange={e => props.dispatch({ type: "submit" })}
/>
</span>
</Text>
</h1>
</div>
</Desktop>
];
}
}
Let me know what you think.. I realise I was jumping around all over the place - so apologies if I've misunderstood what you were trying to achieve..
The other thing you can do is mutate the HUD state directly... Eg:
class SwitchHUDRenderer extends React.Component {
constructor(props) {
super(props);
}
render() {
return [
<Desktop key="Desktop">
<div style={css.desktopHud}>
<h1>
<Text fontSize={['10px', '14px', '20px']}>
<span>
RESIZE
<InputSwitch
checked={props.data.value}
onChange={props.toggle}
/>
MOVE
</span>
</Text>
</h1>
<h1>
<Text fontSize={['10px', '14px', '20px']}>
<span>
<Button
label="RESET"
className="p-button-danger"
onChange={props.reset}
/>
</span>
</Text>
</h1>
<h1>
<Text fontSize={['10px', '14px', '20px']}>
<span>
<Button
label="SUBMIT"
className="p-button-standard"
onChange={props.submit}
/>
</span>
</Text>
</h1>
</div>
</Desktop>
];
}
}
export default () => {
const data = { value: false }
const reset = () => data.value = false;
const toggle = () => data.value = !data.value;
const submit = () => ...
return { data, reset, toggle, submit, renderer: SwitchHUDRenderer };
}
Other systems will be able to read whether the mode is move or resize by inspecting the data.value
property of the switchHud
entity (or whatever you've called your HUD entity).
Ahh yeah that looks like it'll be way more successful... I was trying everything I could to get the state into the right area... and this one was the closest that I got...
const SwitchHUD = (entities) => {
const { switchHud } = entities;
if (switchHud) {
switchHud.mode = switchHud.mode || false;
}
return entities;
};
export default SwitchHUD;
I had a mode in the SwitchHud entity but it was always showing undefined... because args was never anything, even if I set it to something initially and pushed the switchHud mode out by
return { mode => renderer: SwitchHUDRenderer };
Excellent.
I'm used to using a messenger channel Hub for my auth, as a provider, I just wrap it around the
Don't mention it @michaelcuneo - let me know how it goes.
Worked perfectly... but I'm worried a bit about the setting state on the return. I tried solving that by wrapping the function with some state hooks, but realised that the state hooks would still need to reassign the props on return. So I guess there are some scenarios when assigning state on return are acceptable... I just threw in an es-lint ignore...
My switchHud now has this as the switch value and return value...
<InputSwitch checked={props.data.value} onChange={props.toggle} />
export default () => {
const data = { value: false };
// eslint-disable-next-line no-return-assign
const toggle = () => (data.value = !data.value);
return { data, toggle, renderer: SwitchHUDRenderer };
};
I can then use it in the Resize and Drag systems with a simple
const { switchHud } = entities;
if (!switchHud.data.value) drag;
if (switchHud.data.value) resize;
Data goes through well... quite fast and responsive. I can see now how I can add another two values there now for the reset and submit then just perform some tasks accordingly.
I've set up a HUD on my game engine implementation, and the HUD contains three interactive areas, a slider switch for RESIZE/MOVE, and two buttons, RESET and SUBMIT.
Trying to get feedback from the HUD System, so that whatever variables are set in the HUD, can be used within another System. Cannot seem to send/receive props from that side of things... should I implement that area of my HUD into a redux saga to set/get the state?
main.js
entities.js
switchhud.js
switchHud.js
Screenshot of current implementation...
https://haldor.michaelcuneo.com.au/ThreeCircles2.PNG
Is there a way to pull the data in and out of the engine in this case, or should I add saga's, actions, selectors, etc, then just pull the state into the Resize / Move systems, as selected data?
i.e. Resize, runs action to set State of movementMode, movement mode becomes Resize, ResizeSystem sets state to the selected prop movementMode, which is a string 'resize' if(resize) perform resize movements... else return...
Just thought I'd ask if there was something in the system to pull the state in and out before I write tonnes of sagas and such.