Skip to content

Commit

Permalink
Add more corner-case examples to compilation.md
Browse files Browse the repository at this point in the history
  • Loading branch information
fleabitdev committed Jan 12, 2021
1 parent 01e4e35 commit ca7186d
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 5 deletions.
22 changes: 18 additions & 4 deletions website/input/reference/src/compilation.md
Expand Up @@ -64,11 +64,11 @@ glsp::load("scripts/main.glsp")?;
[`compile!`] is very convenient, but it always compiles your source files using an empty,
generic GameLisp runtime. This runtime will have access to the GameLisp standard library and any
macros you define using [`bind-macro!`](../std/bind-macro-mut) or [`defmacro`](../std/defmacro),
but it won't run any of your Rust initialization code, so it won't have access to any libraries,
but it won't run any of your Rust initialization code, so it won't have access to any rglobals,
any Rust functions, any assignments you've made to global variables from within Rust code, and
so on.

This will only matter if you rely on one of your libraries, or call one of your Rust functions,
This will only matter if you access one of your rglobals, or call one of your Rust functions,
in either of the following circumstances:

- When evaluating a toplevel form (see [Evaluation](evaluation.md))
Expand All @@ -81,6 +81,7 @@ the file, and the `Vec<u8>` is the result of compiling it.

It's straightforward to serialize a `Vec<u8>` to a file. The next time your program runs, you
can read that `Vec<u8>` back in, and pass it to [`glsp::load_compiled`] as a byte slice.
The whole process is quite similar to OpenGL shader compilation.

The GameLisp binary format has absolutely no stability guarantees. If you recompile your
executable, then you must also recompile any GameLisp binaries which that executable has produced
Expand Down Expand Up @@ -131,6 +132,13 @@ which calls [`glsp::load_and_compile`] somehow differs from the GameLisp environ
; it to the compile![] macro, rather than glsp::load_and_compile.
(my-sound-library:init)

; this macro stores data in a global variable during expansion, but global
; variables are not serialized by compile![] or glsp::load_and_compile, so
; the global will be empty when the expanded code is actually executed.
(defmacro logged (form)
(push! :log form)
form)

The simplest way to protect yourself against this is to use [`compile!`] rather than
[`glsp::load_and_compile`], and perform all of your loading immediately after calling
[`Runtime::new`], before binding libraries or doing anything else which might modify the
Expand All @@ -141,11 +149,17 @@ GameLisp functions.
[`Runtime`]: https://docs.rs/glsp/*/glsp/struct.Runtime.html
[`Runtime::new`]: https://docs.rs/glsp/*/glsp/struct.Runtime.html#method.new

; this is fine, because it's a fn rather than a macro
; this is fine, because it's a fn rather than a macro.
(defn screen-w ()
(my-window-library:screen-width))

; this is fine, as long as (init-sound) isn't called from the toplevel or
; from a macro expander
; from a macro expander.
(defn init-sound ()
(my-sound-library:init))

; you can take an expansion-time variable and make it available at run-time
; by converting it into a literal.
(do
(let-macro global->literal (name) `(quote ~(global name)))
(= :log (deep-clone (global->literal :log))))
2 changes: 1 addition & 1 deletion website/input/reference/src/rglobal.md
Expand Up @@ -150,7 +150,7 @@ duration of each call to `get-texture`.
When an `rfn` parameter is borrowed from an rglobal, it doesn't consume an argument. You would
invoke this function from GameLisp by calling `(get-texture name)`, with only one argument.

A function may have multiple library parameters:
A function may have multiple rglobal parameters:

```rust
impl Textures {
Expand Down

0 comments on commit ca7186d

Please sign in to comment.