C++ Classes, Interfaces an Flow
From TorqueWiki
Contents |
[edit] Torque Build Envirionment TBE
see Scripting Tools IDEs -- Eclipse and C++
[edit] Compile with gcc/g++for Windows
http://gcc.gnu.org/ml/gcc-help/2005-05/msg00167.html
http://www.bloodshed.net/download.html
http://consoletelnet.sourceforge.net/gccwin32.html
http://www.eclipse.org/downloads/
http://blog.festplatte.ch/?p=285
http://www.garagegames.com/blogs/4280/13914
1) Sun Java SDK installieren: Download unter: http://java.sun.com/downloads/
2) Eclipse downloaden: Download unter: http://www.eclipse.org/downloads/index.php
3) CDT Plugin in Eclipse installieren. Dies am einfachsten direkt über Software-Updates in Eclipse. Der Downloadlink lautet: http://download.eclipse.org/tools/cdt/releases/europa
4) Cygwin installieren Das Setup hier downloaden: http://www.cygwin.com/setup.exe Danach setup.exe ausfüren
Einfach nur die Eclipse platform: http://ftp-stud.fht-esslingen.de/pub/Mirrors/eclipse/S-3.0M8-200403261517/eclipse-platform-3.0M8-win32.zip
Und dazu für die C/C++ Programmierung: CDT http://www.eclipse.org/cdt/
Folgende Dateien benötigst Du für CDT: http://download.eclipse.org/tools/cdt/updates/builds/2.0M8/zips/org.eclipse.cdt-2.0M8-win32.win32.x86.zip http://download.eclipse.org/tools/cdt/updates/builds/2.0M8/zips/org.eclipse.cdt.make-2.0M8.zip http://download.eclipse.org/tools/cdt/updates/builds/2.0M8/zips/org.eclipse.cdt.managedbuilder-2.0M8.zip ... oder Du nutzt die Update-Möglichkeit von Eclipse und trägst dort folgende URL ein: http://update.eclipse.org/tools/cdt/updates/builds/2.0M8
Dann mußt Du nur noch cygwin mit GCC+Debugger installieren und alles ist in Butter. i_hasser 05.05.2004, 15:57 Für Windows gibts eine richtig gute Umgebung die auf mingw32 aufsetzt - dev-c++.
[edit] Links
Engine Interfacing: http://tdn.garagegames.com/wiki/TorqueScript_Quick_Reference_3
Console Types in a most general sense are a way for the console to pass data from the scripting language to C++ code through use of get and set data functions:
Torque/ConsoleTypes
[edit] Patching
http://eviwo.free.fr/torque/torquemerge.html
[edit] Basic Control Flow
[edit] main() Function and Game Main Loop
Initialization occurs in engine/game/main.cc in DemoGame::main():
- initializes libraries and game functions
- cycles in the main game loop
- terminates game
The main.cc overrides DemoGame function:
- processMouseMoveEvent
- processInputEvent
- processTimeEvent
[edit] Simulation steps
- Processes time
- Checks for server network packet sends
- Advances simulation event time
- Processes time for client objects (clientProcess() in engine/game/game.cc)
- Checks for client network packet sends
- Renders the current frame
- Checks for network timeouts
[edit] Platform Layer
Running at the lowest level, it provides a common cross platform, cross architecture interface:
- file and network IO
- graphics initialization
- device initialization and input
- time event generation
- standard library calls are proxied
The platform layer is broken up into cross-platform interface exposed to the game (engine/platform), and the platform specific libraries (engine/platformWin32, engine/platformMacOS, engine/platformX86UNIX).
[edit] GameInterface
The GameInterface class, defined in engine/platform/gameInterface.h:
- interface through which the platform and libraries communicate with the game.
- handler for journaling.
- all platform events are passed through GameInterface::processEvent(), which in turn feeds them to separate virtual event handlers.
- only one instance of this class (or a subclass) exists, a single global pointer named Game points to it.
[edit] Console
The console module in engine/console/console.h, is a combined compiler and interpreter runtime that serves as the foundation for Torque applications:
- All GUIs, game objects, interfaces, and game logic are handled through the console
- language syntactically similar to a typeless C++
- console scripts can be loaded via the exec()
- console command issued from console window loaded via that mod's main.cs.
[edit] Interfacing with C++ Code
The C++ game and engine code can be called from the scripts as described above, and the game code can also call into script using the console execute and evaluate functions.
[edit] Console Language
The scanner and parser were built using the tools lex and yacc.
[edit] Console Functions
Console functions can be declared in either console scripts or in the C++ game/engine code.
In Torque Script:
// A simple script function declaration.
function helloWorld ()
{
echo("Hello World!");
}
// Let's call it!
helloWorld();
// Or, for a method on a class:
function SimObject::helloWorld(%this)
{
echo("Hello World!");
echo("Called on object: " @ %this);
}
// And call it...
$object = new SimObject();
$object.helloWorld();
"this" as first parameter: Unlike in C++, the "this" variable is not implicit in a script's method declaration. Instead, the first parameter to a method is always the object whose method is being called. It is traditional but not required to call this parameter this; a common variant is db, for methods of datablocks.
To declaire in game or engine code use ConsoleFunction macro (declared in engine/console/console.h):
ConsoleFunction(helloWorld, void, 1, 1, "A simple test function.")
{
Con::printf("Hello World!");
}
Arguments:
- name of the function
- minimum and maximum number of allowed arguments. The function name is "argument 0", so 1 is the minimum argument count
- usage string
Methods for classes can also be declared in C++, using the ConsoleMethod macro:
ConsoleMethod(SimObject, helloWorld, void, 2, 2, "A somewhat more complex test method.")
{
Con::printf("Hello World!");
Con::printf("Called on object: %s", argv[1]);
Con::printf("Also called on object: %s", object->getName());
}
This defines a method callable on any instance of a SimObject.
Parameters:
- int argc, indicating how many arguments were passed.
- const char* argv[], an array of strings corresponding to the arguments.
- object, which is present only in the case of a ConsoleMethod, is a pointer to the object on which the method is being called. It is automatically cast and validated, so you don't need to cast it yourself (this was the case in older versions of Torque).
[edit] Classes, Objects and Namespaces
Objects in the scripting language are simply instances of C++ classes deriving from SimObject, declared in the game engine and processed with a special set of macros (declared in engine/console/consoleObject.h).
Data members of C++ classes can be accessed from within the scripting language. The engine maintains a list with the relative addresses of data member in the class.
Dynamically Defined Fields
Member fields of objects can also be defined from within the script itself. For example:
function foo()
{
%object = new SampleObject();
%object.scriptVariable = "Hello World!";
echo(%object.scriptVariable);
}
Fields added in this way are only set and present on the instance on which they were set.
[edit] Namespaces
Namespaces (engine/console/consoleInternal.h) are collections of class member functions. Every SimObject belongs to exactly one namespace. By default, an object belongs to the namespace that corresponds to its class - so an instance of GameBase will have the GameBase namespace. Each namespace has a parent, so methods can invoke parent class methods by calling Parent::function().
New namespaces (not class-based) can be added in the engine via the Con::linkNamespaces() function. Assigning the mNameSpace field of SimObject then assigns the new namespace to an object. For example, in GuiControl::onAdd(), if a control has a name its name is used as its namespace. This allows a named GUI control to have special behaviors.
The ScriptObject class (defined in engine/console/scriptObject.cc) allows for the creation of "classes" within the scripting language:
new ScriptObject(MyObject) {
class = Bar;
superClass = Foo;
};
function Bar::doSomething(%this)
{
echo("Hi!");
}
MyObject.doSomething();
> Hi!
function Foo::doSomething(%this)
{
echo("Hi! Foo");
}
function Bar::go(%this)
{
%this.doSomething();
Parent::doSomething(%this);
}
MyObject.go();
> Hi!
> Hi! Foo
[edit] Packages
- Packages are collections of functions that can be enabled and disabled at runtime.
- Package functions can override (redefine) the behavior of existing functions of packages that have been activated earlier.
- Prior versions of a function can then be accessed using "Parent".
For example:
function foo()
{
echo("foo!");
}
package SamplePackage
{
function foo()
{
echo("Haha!");
Parent::foo();
}
}
% foo();
foo!
% ActivatePackage(SamplePackage);
% foo();
Haha!
foo!
Packages are useful for creating mods to games or for implementing specific game modes.
[edit] Variables
The console language supports global variables and local (function scoped) variables. Global variables are specified by a preceding $, and local variables by a % sign.
[edit] Arrays
The console language supports associative single- and multi-dimensional arrays.
Arrays construct new variables with the names concatenated:
- $array[10] is the same as $array10,
- while $array[3, 4] is the same as $array3_4.
- Strings can be used as array indexes as well: $array["foo"] = 100;
- Array dimensions are separated with commas inside the brackets - $array[1, 0] = 10;
[edit] Simulation
All simulation object classes are derived from GameBase.
- GameBase objects that wish to be notified of the passage of time can be added to: the global server or the global client process list.
- "ticked" once every 32 milliseconds
- Ordering is determined by the GameBase::processAfter method, which is called if an object must be processed at some time after another object (not necessarily immediately afterward).
- Server side objects are only simulated on even tick boundaries, but client objects, in order to present a smooth view when the frame rate is high, are simulated after each time event.
[edit] Simulation Objects
- SimBase (engine/console/simBase.*)
- defines the foundation SimObject classes that form the basis of the simulation engine.
- SimObject
- is the base class for all objects that the console language can create and manipulate. All game classes (Player, InteriorInstance, Terrain, etc.) and GUI classes (GuiCanvas, GuiControl, etc). are all derived from SimObject. SimObject maintains the list of dynamic fields, has name and ID properties, and can register itself with a global object manager.
- SimSet
- is a simple collection of SimObjects.
- SimGroup
- is a derivative of SimSet that "owns" the objects in its collection. When a SimGroup object is destroyed, it destroys all of its members. GuiControl is derived from SimGroup - thus making the GUI a hierarchal set of objects.
Objects are collected in a hierarchy of SimGroups and can be searched for by name or by object id.
- SimEvent
- is a special class objects can use to send time-delayed messages to objects.
- SimManager
- (engine/console/simManager.cc) is a collection of functions for managing all of the objects and events in the simulation.
[edit] Persistence and Inspection
Objects in Torque can be saved to a script file using SimObject::save(). This basically dumps the current state of all the object's registered fields and dynamic fields, as well as, in the case of a SimGroup, all of that object's sub objects.
[edit] Container Database
Container maintains a database on both client and server for objects positioned in the simulation. It supports a set of functions for quickly inserting, removing and moving objects in the world (Container::addObject, Container::removeObject, Container::checkBins), as well as query functions for line, box and polyhedron intersection tests (Container::castRay, Container::collideBox, Container::findObjects).
[edit] Files, Streams and the Resource Manager
Resources:
- terrain files,
- bitmaps,
- shapes,
- material lists
- fonts and interiors
- ..
Resources have the special property that only one instance of a resource will ever be loaded at a time.
[edit] Resource Manager -- ResManager
- Resource objects are reference counted so that when a second request is made for the same resource, the original loaded instance is returned.
- A list of searchable paths are fed to the ResManager via the setModPaths() function. This function also scans the specified paths for all the files contained therein, creating a ResourceObject for each one. These are all stored in a ResDictionary, allowing rapid lookup of a specified file.
- In addition, a writeable path may be set using setWriteablePath(). The writable path is used to store files downloaded from game servers.
- The Resource system also supports Volume files, which are ZIP files. When ResManager encounters a file with a .zip extension, it opens it and adds all the items in the ZIP's contents list to the list of known files.
[edit] Rendering
Torque has a modular, extensible 3D world rendering system. Subclasses of the GuiTSCtrl override the GuiTSCtrl::processCameraQuery() and GuiTSCtrl::renderWorld() methods to define the camera orientation/FOV, and draw the 3D scene using OpenGL drawing commands respectively. GuiTSCtrl manages setting up the viewport, modelview matrix and projection matrix. The Torque example code GameTSCtrl class calls the global functions GameProcessCameraQuery() and GameRenderWorld(). GameProcessCameraQuery() returns the viewing camera of the current control object (the object in the simulation that the player is currently controlling), then GameRenderWorld makes the client scene graph object render the world.
[edit] SceneGraph
The scene graph library (engine/sceneGraph) is, on the client, responsible for traversing the world scene and determining which objects in the world should be rendered given the current camera position, and on the server, determines what objects should be sent to each client based on that client's position in the world.
[edit] Zones
The world in the SceneGraph is divided into zones - volumes of space bounded by solid areas and portals. The outside world is a single zone, while interior objects can have multiple interior zones. SceneGraph::findZone() finds the zone of a given 3D point and reports which SceneObject owns that zone. SceneGraph::rezoneObject() determines which zone or zones contain a SceneObject instance. At render time, the scene is traversed starting from the zone that contains the camera, clipping each zone's objects to the visible portal set from the zones before it. Scoping of network objects is performed in SceneGraph::scopeScene().
[edit] scene graph traversal
The scene graph traversal is complicated by transform portals. Transform portals are objects like mirrors or teleporters through which the world can be viewed using a different transform than the normal camera transform. When SceneGraph::buildSceneTree() encounters an object with a transform portal, it constructs a new SceneState object for rendering that portal's contents.
Every renderable world object in the scene derives from the SceneObject base class. As the world is traversed, visible objects are asked to prepare one or more SceneRenderImage objects (in SceneObject::prepRenderImage()) that are then inserted into the current SceneState via SceneState::insertRenderImage(). Render images are sorted based on translucency and rendered from SceneObject::renderObject(). This system allows, for example, an interior object with multiple translucent windows to render the building first, followed by other objects, followed by the building's windows. Objects can insert any number of images for rendering.
