---------------------------
---------------------------
-- Tutorial: Hello world
-- Your first script
--
-- We suggest looking at the Lua reference manual bundled with the
-- ScriptENGINE Help to get a better understanding of the language
--
-- Copyright (c) 2006-2008 Capricorn 76 Pty. Ltd.
---------------------------
---------------------------
--[[
This is a lua block comment that can span multiple lines and ignored by ScriptENGINE.
A line comment starts with --
]]
---------------------------
-- Global and local variables
--
-- Lua is a dynamically typed language.
-- That means that variables do not have types; only values do.
-- There are no type definitions in the language.
-- All values carry their own type.
--
-- There are eight basic types in Lua: nil, boolean, number, string, function, userdata, thread, and table.
-- Nil is the type of the value nil, whose main property is to be different from any other value; usually it represents the absence of a useful value.
-- Boolean is the type of the values false and true. In Lua, both nil and false make a condition false; any other value makes it true.
-- Number represents real (double-precision floating-point) numbers. (It is easy to build Lua interpreters that use other internal representations for numbers, such as single-precision float or long integers.)
-- String represents arrays of characters. Lua is 8-bit clean: Strings may contain any 8-bit character, including embedded zeros ('\0'). Strings are defined in single or double quotes.
-- ScriptENGINE has extended Lua to also support wide-strings (Unicode). Wide strings may contain any 16-bit character, including embedded zeros. Wide strings are defined using the L"This is a wide sting" syntax.
-- The Lua library function type(v) returns a string describing the type of a given value
--
-- Variables are places that store values. There are three kinds of variables in Lua: global variables, local variables, and table fields.
---------------------------
a = 5; -- This is a global variable, accessible from all loaded scripts, and assigned a number
local b = 'Trevor'; -- This is a local variable, accessible only in this script, and only by functions declared below this line.
local c; -- Variables are assigned nil if no other value is used.
---------------------------
-- Garbage collection
--
-- Lua automatically manages garbage collection,
-- but you can manually control it too.
---------------------------
local function garbageCollectFunction()
collectgarbage(0); -- Force garbage collector to run immediately
end
---------------------------
-- Global functions
--
-- This is a global function, accessible from all loaded scripts including ScriptENGINE.
-- Your ScriptENGINE callbacks must be globally defined functions...
---------------------------
function globalFunction(param1, param2)
print('Inside the global function', param1); -- Calling a Lua library function.
end
---------------------------
-- Local functions
--
-- This is a local function, accessible only in this script, and only by functions declared below this line.
---------------------------
local function localFunction(param1, param2, param3)
print('Inside the local function', param1, param2, param3);
globalFunction(param1, param2); -- Calling one Lua function from another
local f = globalFunction; -- Functions can also be stored in variables.
f(param2, param3); -- Then you can call the functions using the variable (it's like a function pointer)
end
---------------------------
-- Functions with return values
--
-- Your functions can return 1 or more values to their calling function by separating the return values with a comma
-- By default, all functions will return nil is no other values are returned.
---------------------------
local function returningFunction()
return 'value1', 1, 4.5;
-- To grab all the return values, your calling function would look something like:
-- local v1, v2, v3 = returningFunction()
end
---------------------------
-- Lua control structures: if-statements, for-loops, while-loops
---------------------------
local function loopFunctions(totalLoops)
-- Check the input parameter. Make sure it was defined (if not, we'll assign a default value)
if (not(totalLoops)) then
totalLoops = 10;
end
if (totalLoops > 100) then -- Check that input param is not too large
totalLoops = 100;
end
local i; -- The variable is assigned 'nil' by default
for i = 1, totalLoops do
print('loopFunctions for-statement:', i);
end
i = totalLoops;
while i > 0 do
print('loopFunctions while-statement:', i);
i = i - 1;
end
end
---------------------------
-- Lua tables
--
-- Lua tables are one of the most important parts of the language. They are very powerful.
-- Think of lua tables like arrays on steroids.
-- Tables can hold any lua data type, including other tables.
---------------------------
local function tableFunction()
local exampleEmptyTable = {};
local tableIndexedWithNumbers = {'value1', 'value2', 'value3'};
local tableIndexedWithStrings = {val1='value1', val2='value2', val3='value3'};
-- Accesing table values in a range of styles
-- Notice that you can use the dot-notation to access names table values. this is the basis to creating objects in Lua
print('Table values:', tableIndexedWithNumbers[1], tableIndexedWithStrings['val1'], tableIndexedWithStrings.val2);
-- Iterating tables
local i;
for i = 1, table.getn(tableIndexedWithNumbers) do
-- Demonstrating string-concatenation with the double-dot notation
print('tableIndexedWithNumbers ' .. tostring(i) .. ':', tableIndexedWithNumbers[i]);
end
-- Inserting an item into the table
table.insert(tableIndexedWithNumbers, 2, 'value4');
-- Iterating tables using the Lua pairs() function
local v;
for i, v in pairs(tableIndexedWithNumbers) do
print('tableIndexedWithNumbers B ' .. tostring(i) .. ':', v);
end
for i,v in pairs(tableIndexedWithStrings) do
print('tableIndexedWithStrings ' .. tostring(i) .. ':', v);
end
end
---------------------------
-- Lua coroutines
--
-- These are different to ScriptENGINE threads and not actually running in separate thread.
-- Instead they provide different execution paths, that you can switch between.
---------------------------
function foo (a)
print("foo", a);
return coroutine.yield('Yielding from foo'); -- This will stop execution of the current coroutine, and return.
end
local function coroutineFunction(a)
print("coroutineFunction:", a);
local r = foo('Called from coroutineFunction'); -- The coroutine will yield exection at this point
print("foo returned to coroutineFunction:", r); -- When resumed, the coroutine will restart here
local r = coroutine.yield('Yielding from coroutineFunction'); -- Yielding again, the coroutine will stop execution
print("coroutineFunction resumed:", r); -- When resumed, the coroutine will restart here
return "coroutineFunction complete"; -- Coroutine complete, can no longer be resumed
end
local function runCoroutineFunction()
-- Create a coroutine, using a pre-defined function.
-- The coroutine.wrap function is an alternate method for creating a coroutine
local co = coroutine.create(coroutineFunction);
local yieldResult, returnValue;
yieldResult, returnValue = coroutine.resume(co, 'Starting coroutineFunction'); -- Start coroutine
print("main", yieldResult, returnValue); -- After the 1st yield, the coroutine will return to here
yieldResult, returnValue = coroutine.resume(co, "Resuming coroutineFunction 1"); -- Resume coroutine
print("main", yieldResult, returnValue); -- After the 2st yield, the coroutine will return to here
yieldResult, returnValue = coroutine.resume(co, "Resuming coroutineFunction 2"); -- Resume coroutine
print("main", yieldResult, returnValue); -- After the 3st yield (the return call), the coroutine will return to here
yieldResult, returnValue = coroutine.resume(co, "Resuming coroutineFunction 3"); -- Can no longer resume the coroutine. It's dead
print("main", yieldResult, returnValue);
end
---------------------------
-- Calling ScriptENGINE interfaces
--
-- One of the first things you'll need to learn is how to call an ScriptENGINE function.
-- Here, we are using the IApp interface to open the console window.
-- If you don't explicitly pass a function parameter to ScriptENGINE, it will default to [nil/0/false/''] depending upon the input data type.
---------------------------
local function startConsole()
IApp:showConsoleWindow(); -- This will open the console window, so our print statements are displayed
end
---------------------------
-- Creating Lua classes.
-- Lua can be extended to support classes and objects.
-- ScriptENGINE supplies functions in the IMisc interface to define classes & create class instances.
-- The ScriptENGINE class implementation supports constructors, destructors, and polymorphism (ie. virtual functions).
---------------------------
local function luaClassExample()
---------------------------
-- Create a class definition
-- Must call this function before any other class functions are defined
---------------------------
myclass = IMisc:classDefine(nil); -- The class function can take a base class as a parameter. It will inherit all the base class functions.
---------------------------
-- Define class constructor using name __construct().
-- Supply your input parameters, these will be passed into the constructor from the IMisc:classCreateInstance() function
---------------------------
function myclass:__construct(param1)
print('myclass:__construct:', param1);
self.value1 = param1;
end
---------------------------
-- Define class destructor using name __destruct().
-- Supply your input parameters, these will be passed into the constructor from the IMisc:classCreateInstance() function
-- The destructor is automatically called by the Lua garbage collector when all references to a class instances have been set to nil.
---------------------------
function myclass:__destruct()
print('myclass:__destruct');
end
---------------------------
-- Define some class functions
---------------------------
function myclass:getParam()
return self.value1;
end
function myclass:setParam(newValue)
self.value1 = newValue;
end
function myclass:func(param1)
print('myclass:func:', param1);
end
---------------------------
-- Create a new instance of the class, and call its functions
---------------------------
local obj = IMisc:classCreateInstance(myclass, 99); -- Construct a new object. Supply input parameters.
-- Call a class-function on the object instance
obj:func('abcd');
-- Access the object's data using a class-function
print('myclass:getParam:', obj:getParam());
-- Set the object reference to nil. All references to this object are now nil,
-- and Lua's garbage collector will collect this object (calling its destructor)
-- on the next garbage collecting cycle.
obj = nil;
-- Force Lua to run its gabage collector immediately, so we can see the destructor being called
collectgarbage();
end
---------------------------
-- Debugging ScriptENGINE programs
--
-- The IDebug interface provides some utility functions to debug your programs.
-- You can either access the debug data and present it in your own style (ie. via a GUI)
-- or use the output functions that write the debug info to the console.
---------------------------
local function showCallstack()
local ci, li = 1, 1;
local call_info, local_name, local_value;
repeat
call_info = debug.getinfo(ci);
if (call_info) then
-- Print the callstack information
print('====' .. (ci - 1) .. '====');
table.foreach(call_info, print);
-- Print the local variables
li = 1;
print('---- Locals ----');
repeat
local_name, local_value = debug.getlocal(ci, li);
if (local_name) then
print(local_name, local_value);
li = li + 1;
end
until (local_name == nil);
ci = ci + 1;
end
until (call_info == nil);
end
---------------------------
---------------------------
-- SCRIPT - ENTRY - POINT
-- Code not explicitly placed in a function will be executed as soon as the script is loaded.
-- It's the entry-point to your ScriptENGINE programs.
---------------------------
---------------------------
-- Calling ScriptENGINE functions example
startConsole();
-- Local function example
print('\n### Calling local and global functions. Press any key to start...');
IKey:getch(); -- Wait for the user to press a key
localFunction("a", 5, true);
-- Functions with return values example
print('\n### Using functions with return values. Press any key to start...');
IKey:getch(); -- Wait for the user to press a key
local v1, v2, v3 = returningFunction();
print('returningFunction:', v1, v2, v3);
-- Loop functions example
print('\n### For and while loops. Press any key to start...');
IKey:getch(); -- Wait for the user to press a key
loopFunctions(5);
-- Table example
print('\n### Table example. Press any key to start...');
IKey:getch(); -- Wait for the user to press a key
tableFunction();
-- Coroutine example
print('\n### Coroutines example. Press any key to start...');
IKey:getch(); -- Wait for the user to press a key
runCoroutineFunction();
-- Lua class example
print('\n### Lua class example. Press any key to start...');
IKey:getch(); -- Wait for the user to press a key
luaClassExample();
-- Display debug info
print('\n### Viewing debug information. Press any key to start...');
IKey:getch(); -- Wait for the user to press a key
showCallstack();
print('\n### Tests complete. Press any key...');
IKey:getch(); -- Wait for the user to press a key
Copyright © 2006-23 Sep 2009 Capricorn 76 Pty. Ltd. (created on Wed Sep 23 16:49:11 2009)