--======================================================================== -- PreInit.lua : Script that's run when the scripting system is initialized -- -- Part of the GameCode4 Application -- -- GameCode4 is the sample application that encapsulates much of the source code -- discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David -- "Rez" Graham, published by Charles River Media. -- ISBN-10: 1133776574 | ISBN-13: 978-1133776574 -- -- If this source code has found it's way to you, and you think it has helped you -- in any way, do the authors a favor and buy a new copy of the book - there are -- detailed explanations in it that compliment this code well. Buy a copy at Amazon.com -- by clicking here: -- http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller= -- -- There's a companion web site at http://www.mcshaffry.com/GameCode/ -- -- The source code is managed and maintained through Google Code: -- http://code.google.com/p/gamecode4/ -- -- (c) Copyright 2012 Michael L. McShaffry and David Graham -- -- This program is free software; you can redistribute it and/or -- modify it under the terms of the GNU Lesser GPL v3 -- as published by the Free Software Foundation. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See -- http://www.gnu.org/licenses/lgpl-3.0.txt for more details. -- -- You should have received a copy of the GNU Lesser GPL v3 -- along with this program; if not, write to the Free Software -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -- --======================================================================== -- This file is run immediately after Lua is created but before the rest of the game initializes. This is the place -- to put any language extentions or pure utility functions/classes you write. ----------------------------------------------------------------------------------------------------------------------- -- Redifinition of require() and dofile(). This is needed to allow scripts to go through the resource system. ----------------------------------------------------------------------------------------------------------------------- do local OldRequire = require; -- save the old require() function local resourceIdMap = {}; -- map of resource id's we've already loaded require = function(script) -- If we haven't already loaded this file, try to load it now if (not resourceIdMap[script]) then if (LoadAndExecuteScriptResource(script)) then resourceIdMap[script] = true; else -- failed to load file through the resource system so fall back to the old method OldRequire(script) end end end end do local OldPrint = print; print = function(text) if (text ~= nil) then Log(text); else Log(""); end end end ----------------------------------------------------------------------------------------------------------------------- -- Utility functions ----------------------------------------------------------------------------------------------------------------------- Utils = {}; function Utils.DumpTable(table) for key, val in pairs(table) do print(key, val); end end -- private function used by Utils.DumpObject() function Utils._BuildMemberSet(obj, memberSet) if (obj.__index ~= nil and obj ~= obj.__index) then Utils._BuildMemberSet(obj.__index, memberSet); end for key, val in pairs(obj) do if (key ~= "_index" and memberSet[key] == nil) then memberSet[key] = true; end end end function Utils.DumpObject(obj) -- There might be copies of the same variable at various levels in the hierarchy so we need to build an -- exclusive set of names. local memberSet = {}; Utils._BuildMemberSet(obj, memberSet); -- Loop through the set of member names and print them out, along with the value from the original object's -- perspective. for key,val in pairs(memberSet) do print(key, obj[key]); end end ----------------------------------------------------------------------------------------------------------------------- -- Classes & Inheritance - Chapter 12, page 349 ----------------------------------------------------------------------------------------------------------------------- function class(baseClass, body) local ret = body or {}; -- if there's a base class, attach our new class to it if (baseClass ~= nil) then setmetatable(ret, ret); ret.__index = baseClass; ret.base = baseClass; end -- Add the Create() function. This will end up being added to each subclass which isn't ideal. This -- function should probably be stored in a single place so we only have to create it once. -- -self: The self pointer that's calling this function. -- -constructionData: The table sent in as construction data. Think of it like a constructor. -- -originalSubClass: Used for recursion. Don't pass anything into this parameter, it's filled -- automatically. It's used in case the C++ side needs access to the leaf -- subclass that is being instantiated. For an example, see ScriptProcess -- in C++. ret.Create = function(self, constructionData, originalSubClass) local obj; if (self.__index ~= nil) then if (originalSubClass ~= nil) then obj = self.__index:Create(constructionData, originalSubClass); else obj = self.__index:Create(constructionData, self); end else obj = constructionData or {}; end setmetatable(obj, obj); obj.__index = self; -- copy any operators over if (self.__operators ~= nil) then for key, val in pairs(self.__operators) do obj[key] = val; end end return obj; end -- Returns true if otherClass appears in this objects class hierarchy anywhere. ret.IsInstance = function(self, otherClass) local cls = self.__index; while cls do if cls == otherClass then return true end cls = cls.base end return false end return ret; end