Sei sulla pagina 1di 6

PROGRAMMING COMMENTS

PROGRAMS

ORTS has three executable programs:

Users launch ORTS with ORTS.exe - all it does is verify dependancies are installed.
This program
appears in Visual Studio as Launcher. Once dependancies are checked, ORTS.EXE
executes MENU.EXE.

MENU.EXE presents a menu for selection of the mini-route, route, and activity. It
also meant in
the future to provide settings for details levels, performance etc. Once a route
is selected
it executes RUN.EXE

RUN.EXE is the program that runs an activity.


It consists of a railroad Simulator module with one or more Viewers attached.

The simulator engine contains all the elements for an operational route including
representation
of signal conditions, switch track alignment, rolling stock location and movement,
track paths,
AI logic, physics calculations, essentially everything except the 3d representation
of the objects.
It is intended that the simulator engine could run in separate thread, or even on a
separate computer.

There can be multiple viewers looking at the simulator - ie straight down activity
editor type views,
or full 3D viewers, or perhaps in the future Tower operator's panels etc. The 3D
viewer is
responsible for loading and rendering all the shape files in the
scene. It also handles movement of wheels and other animations embedded in the
shape files.

The source code consists of the following sub folders:

Main - contains the openning dialog boxes to select a route and launch the
sim
Simulator - contains the simulation processes, including physics, ai etc
3DViewer - contains the code for rendering the Simulator data in 3D on a
users computer
MSTS - contains code for reading and processing MSTS files
Physics - contains rolling stock classes - these files contain only
simulation behaviour - no rendering classes are included
Common - classes common to the others

THREADING - the program is designed to make maximum use of multiprocessing. There


are at least three
threads planned:
- the main thread runs the 3d viewer
- a second thread handles background loading and unloading assets into the viewer -
this is complete now
- the simulator engine engine will run in a third thread ( not done yet )
- the sound engine operates in a fourth thread.
Notes: Use care to ensure drawablecomponent objects are fully initialized before
adding them to the viewer.components list.

TIMING - as the simulator engine runs in a separate thread, and possibly on a


separate computer, it
does not run necessarily in sync - TODO how will we handle this

ERROR HANDLING STRATEGY


- ORTS will always attempt to complete the load even in the presence of errored or
missing files
- when it encounters a recoverable error, it will list them in a ORTS
Warnings file on your desktop
- in order to continue, ORS may omit objects, use defaults etc
- if it can't continue, it will report the situation in a message box, and in the
ORTS Warnings file and exit.

SCALAR UNITS
- meters are assumed for coordinates
- other scalers must have units appended, ie MpS, N, KG, MpS2 etc to avoid mistakes
- R = radians
See also the info in Coordinates.cs on the coordinate spaces used in ORTS

TODO - use this comment to flag incomplete parts of your code.

COMMENTING STYLE

I place a lot of value on having a paragraph or two at the top of each file
explaining what it contains,
how the classes are used, and a few details about the internals. I find this more
useful than embedded
comments in the code so if you have to take shortcuts in commenting, try to at
least provide the file header
comment block.

ERROR HANDLING

General practice on errors is to report and continue.


- Console.Error.WriteLine( errormessage )
- then make adjustments, ie defaults etc to continue
If you can't continue, throw an exception
- and attempt to handle it further up

ROLES PROPOSED
1 - engineer - in future, number cycles through engineers on train
- arrows move - right - headout, left - head in
- home end, page down, page up - must be stopped while on the ground
2,3,4 - railfans
6 - brakeman1
7 - brakeman2
ctrl left right, moves from car to car
pgdn, on the ground
pgup, on the train , nearest car
home, front of train
end, back of train
5 - passenger
up down, home, end - move along train
- railfan
- pgup - home, end, up, down
- pgdn - on the ground

9 - fireman - in future, number cycles through fireman on train


- arrows move - right - headout, left - head in
- home end, page down, page up

public Viewer3D(Simulator simulator)

public void UserSetup()

public void Configure(RenderProcess renderProcess)

public void Initialize(RenderProcess renderProcess)

public void LoadPrep()

public void Load( RenderProcess renderProcess )

public void HandleUserInput()

public void Update( GameTime gameTime )

public void PrepareFrame(RenderFrame frame, GameTime gameTime)

void Render(GraphicsDevice graphicsDevice, Material previousMaterial,


RenderPrimitive renderPrimitive,
ref Matrix XNAWorldMatrix, ref Matrix XNAViewMatrix,
ref Matrix XNAProjectionMatrix);

void Draw(GraphicsDevice graphicsDevice);

void ResetState(GraphicsDevice graphicsDevice, Material nextMaterial);

public void Unload(RenderProcess renderProcess)

SIMULATOR

public TrainCar(WAGFile wagFile)

public virtual TrainCarViewer GetViewer(Viewer3D viewer)

public virtual void Update(GameTime gameTime)

VIEWER

public virtual void HandleUserInput()

public virtual Update(GameTime gameTime)


// Processes
///
/// Open Rails can use multiple processors. In a multiprocessor environment,
/// we set up the following threads:
/// - the RenderProcess thread
/// - is actually the XNA game engine thread
/// - handling initializing and drawing to the graphics card
/// - a LoaderProcess thread runs in the background
/// - 10 times per second
/// - to give the 3D viewer an opportunity to load content as the
player moves
/// - an UpdaterProcess thread runs in the background
/// - updating the simulator state
/// - and preparing content for the next rendered frame to be drawn
/// - in additon, IrrKlang, can be configured to run in its own separate thread
///
/// Thread Safety:
///
/// Thread safety is maintained more by data partitioning rather than through the
use
/// of semaphores or locks (which can slow down the program). UpdaterProcess, has
/// exclusive access to all input devices, all simulator state data and local
matrices for
/// 3D components. Information exchange with the main render process is through
the
/// RenderFrame class. UpdaterThread prepares a RenderFrame ( list of primitives
and
/// their position matrices ) and hands it off to the RenderProcess for drawing.
While
/// RenderProcess does the drawing, UpdaterProcess is preparing the next frame.
/// RenderProcess is assured that the RenderFrame contents won't change after it
begins
/// drawing.
///
/// LoaderProcess needs access to volatile data in the simulator and viewer classes
such
/// as train location and camera location. To make this thread safe,
RenderProcess calls
/// LoaderProcess.Update as soon as UpdaterProcess has finished with the simulator
and
/// viewer classes. UpdaterProcess will be blocked while LoaderProcess copies any
needed
/// volatile data. When LoaderProcess.Update returns, the UpdaterProcess continues
on with
/// updating train location and camera locations for the next frame. Meanwhile
LoaderProcess
/// analyzes the data it copied and continues with loading/unloading graphics
content as
/// needed.
///
/// Process Synchronization:
///
/// These processes don't free-wheel. In order to prevent jitter and memory
contention
/// they operate synchronously to the frame rate. Each frame triggers
UpdaterProcess
/// to update the Simulator state, and to build a RenderFrame. While thats being
done,
/// RenderProcess draws the previous RenderFrame. LoaderProcess is launched by
/// UpdaterProcess immediately after the UpdaterProcess has finished.
/// Note that when the program is minimized no frame draw calls are made. During
this
/// time, RenderProcess continues to update the LoaderProcess and the Simulator
state
/// at a fixed 10 times per second rate.
///
/// And on machines with only one processor, we eliminate UpdaterProcess to reduce
the
/// overhead of frame swapping etc.

public virtual void PrepareFrame(RenderFrame frame, GameTime gameTime)

public virtual void Unload()

TIME
----

The following time variables are used:

double Program.RealTime
- global static variable representing number of seconds the program has been
running

double Simulator.ClockTime
- class variable representing the number of seconds since 00:00:00 on the day of
the activity, this
clock stops when the game is paused, and runs fast when the game is sped up.

When various objects are updated, they are passed an elapsed time consisting of one
of the following:

struct ElapsedTime
float RealSeconds;
float ClockSeconds;

This represents the elapsed time since that function was last called in both real
time and clock time
units. Functions interacting with the player generally want to use real time, ie
camera motion doesn't
stop when the game is stopped. Functions related to animating game elements, ie
wheels turning, use
clock time.

At a certain point it doesn't make sense to propagate both types of time. For
example, the simulator
classes ( ai, signals etc ) have no concept of real time and work only in clock
time. To avoid errors,
they recieve a float elapsedClockSeconds parameter to eliminate any possibility of
error.

Also there are other classes that receive only a float elapsedRealSeconds
parameter.

Most floating point variables in Open Rails are stored as float's including elapsed
time. But notice
that to avoid accumulated errors, ClockTime and RealTime are doubles. Keep that in
mind if you have
to create variables that store one of these values.

The times always represent the target time of the frame currently being prepared
and rendered.

All timekeeping is handled in the UpdaterProcess ( see the Architecture Diagram )


for thread safety
reasons. If any other process is examining time variables, there is probably
something wrong and
warning bells should go off.

TRAINCARS
---------

Custom parsers.
Don't even need a parser.

Potrebbero piacerti anche