Archive for June, 2013

Qk’s Squirrel “Reloading Scope” Guide

Wednesday, June 12th, 2013

This is a preliminary document. A first pass, a draft, talking through implementation notes from a piece of a project with the working name “Qk”. It might be something cool. I’m not telling. ;D

The programming language seen below is squirrel, but this specific nuance is something in my engine.


Reloading Scope

“Reloading Scope” is another name for the Global Scope of a script file. Take the follow code:

The variable Pos is in the global scope. Any and all code found in the global scope will be executed every time a script file is changed (automatically reloaded). So every single time this file reloads, Pos will reset back to [0,0]. This may not be the desired effect, as you may want the position to stay the same across changes.

To remedy this, simply move the code in to function scope.

REMEMBER: Both of these snippets effectively do the same thing, creating a global variable called Pos (in the root table). The only difference is the idea of “Reloading Scope” presented above.

Constants in Reloading Scope

For the most part, constants should be placed in Global Scope. This way, if you decide to change their meaning, the changes will affect all future references to the variable.

“Hard-coded” Data and Delagates in Reloading Scope

When code is dynamically reloaded, “hard-coded” isn’t really that “hard-coded” anymore. 😀

Delegates should be set immediately after the data is populated INSIDE the global scope. This way, during subsequent reloads when it trashes the old data, all your standard functions and default values continue to work correctly.

File Dependencies in Reloading Scope

Understanding Reloading Scope is important due to the way automatic dependencies work. All files that depend on this file will be flagged and reloaded at the same time. So changing this file may inadvertently cause another file to reload.

Each file is reloaded at max 1 time per refresh in Usage Order.

Usage Order is the order in which the files were referenced by each-other, starting with the root file (main.nut). Issuing a “requires()” command DOES NOT load a file, but instead queues it to load immediately after the current list of files have finished loading.

This is fine for code written for Function Scopes, but can be troublesome for Reloading Scope. After all, the newest version of a constant or class defined in a later file will be inaccessible/incorrect until all files have been loaded.

To work around this, push a function on to OnReload array. All functions in the OnReload array will be called immediately after all files have finished loading due to a refresh.

TODO: Consider priority model, giving functions inside OnReload a weight to control who gets called first/last. i.e. qkOnReloadCall( function(){}, Weight ); // Weight is optional. Default 0, highest first //

TODO: Consider “include()” function too which, if supported by squirrel compiler and VM, recursively compiles and executes code files on demand before finishing other ones. Need an #ifndef #define #endif construct, or #pragma once like function (global array of parent files, updated according to depth). Discourage the usage of this, but support it for hackability. “include()” should be thought of and used like a macro. “dofile()”. Overload sqstdlib dofile()?