The funny game unForGetTable (development name mem6)
is a PWA - progressive web app.
https://github.com/bestia-dev/mem6_game
It works completely in the browser with wasm/webassembly.
The web server is not really important.
It is just a web file server and a simple websocket server
to send messages to other players. No logic on the server.
All starts with index.html
. It contains this parts:
- classic header for a web page
- a lot of metadata for PWA (android and iOS): manifest.json, mobile-web-app, icons
- a call to start service worker for PWA
- warning if the browser cannot run javascript
- a text to display while loading, because it can take some time
- import and init of wasm code
- roboto google font saved on my server
- html defaults
- screen width between 300 and 600 px is ok for the game
- background color black as in dark theme
- the game should be full screen especially when started from Home Screen
- css reset
- svg elements, not-clickable by default
- colors separated in css classes
- use of h1, h2,... as font size also in svg elements as class
- all style is in css, nothing is in html, so it is easier to modify
- blinker animation
This is a "single page" app so the start of wasm is only one time here:
- console_error_panic_hook
- websocketmod::setup_ws_connection - the main way of communication is ws
- RootRenderingComponent::new - all the data is here and the Render trait
- dodrio::Vdom::new - the main object of dodrio virtual dom is always present everywhere
- fetch data from server: game_config, videos, audio,
- start_router - run immediately and on every hash_change
start_router
: the Closure takeslocation.hash
. This is a short_route ex.#p03
update_rrc_local_route
- updates therrc.local_route
with the filename ex.p03_join_a_group.html
async_spwloc_fetch_text
- fetch the html templatebetween_body_tag()
- the html_template is a complete html file. It can be viewed correctly in the browser. It does not yet have any dynamic parts. This is great because the graphical designer can make changes on a true html file. The programmer after that adds comments that are actions for the templating engine. For the templating engine we need only the body part.- searches for "template" nodes, drains them and saves them in
rrc.html_sub_templates
for later use update_rrc_html_template
- updatesrrc.html_template
Only one function Render() in impl Render for RootRenderingComponent
.
It is scheduled when the data changes.
- takes
rrc.html_template
and start the templating torender_template()
. - after that in a tick the dodrio vdom will make its magic: find the diffs and update the real dom.
- render_template() returns a complete single
dodrio::Node
- parses the html_template with
ReaderForMicroXml
- create
dodrio::Nodes
withElementBuilder::new
- there is a difference between Html nodes and Svg nodes. The latter must have a namespace.
- calls
fill_element_builder
that recursively goes through all nodes - adds attributes with
element.attr()
- if it finds
data-t-
attributes then callscall_fn_string()
with the value. The resulting string is saved toreplace_string
. Then goes to the next attribute and replace the value with the result. - if it finds
data-on-
attribute then callscall_fn_listener()
with the value. The result is aClosure
that is added to the event listener named in the last word ex.data-on-click
. - the TextNode is
decoded_for_xml
- if it finds a comment like
<!--t=
it willcall_fn_string
and updatereplace_string
. The next TextNode will be replaced with this result. - if the comment is like
<!--n=
it willcall_fn_node
and updatereplace_node
. The next Node will be replaced with this result. - if the comment is like
<!--v=
it willcall_fn_vec_nodes
and updatereplace_vec_nodes
. The next Node will be replaced with all this nodes. - if the comment is like
<!--b=
it willcall_fn_boolean
and updatereplace_boolean
. The next node will NOT be rendered if the result is false.
The code can use saved rrc.html_sub_templates
and render them with the same code
and so include them in the main template.