Add autogeneration of PDF documentation for qtscript API using LaTeX.

master
Per Inge Mathisen 2011-12-29 02:19:30 +01:00
parent 0945972f1a
commit 30f9c0091f
4 changed files with 156 additions and 32 deletions

View File

@ -50,3 +50,12 @@ EXTRA_DIST= \
dist-hook:
rm -rf `find $(distdir) -type d -name .svn`
javascript-doc:
grep $(top_srcdir)/src/qtscript.cpp -e '//==' | sed 's/\/\/==//' > doc/globals.tex
grep $(top_srcdir)/src/qtscriptfuncs.cpp -e '//==' | sed 's/\/\/==//' >> doc/globals.tex
grep $(top_srcdir)/src/qtscript.cpp -e '//__' | sed 's/\/\/__//' > doc/constants.tex
grep $(top_srcdir)/src/qtscriptfuncs.cpp -e '//__' | sed 's/\/\/__//' >> doc/constants.tex
grep $(top_srcdir)/src/qtscript.cpp -e '//--' | sed 's/\/\/--//' > doc/functions.tex
grep $(top_srcdir)/src/qtscriptfuncs.cpp -e '//--' | sed 's/\/\/--//' >> doc/functions.tex
cp $(top_srcdir)/doc/javascript.tex doc/
(cd doc ; pdflatex javascript.tex)

32
doc/javascript.tex Normal file
View File

@ -0,0 +1,32 @@
\documentclass[12pt]{article}
\usepackage{listings}
\usepackage{underscore}
\lstloadlanguages{C++}
\lstset{language=C++, frame=trBL, aboveskip=15pt, belowskip=15pt, xleftmargin=20pt, xrightmargin=20pt}
\title{Warzone2100 JavaScript Scripting API}
\date{}
\begin{document}
\maketitle
\section{Introduction}
\section{Globals}
\flushleft
\begin{description}
\input{globals}
\end{description}
\section{Constants}
\flushleft
\begin{description}
\input{constants}
\end{description}
\section{Functions}
\input{functions}
\end{document}

View File

@ -39,6 +39,7 @@
#include "lib/framework/file.h"
#include "lib/gamelib/gtime.h"
#include "multiplay.h"
#include "map.h"
#include "qtscriptfuncs.h"
@ -110,6 +111,41 @@ static bool callFunction(QScriptEngine *engine, const QString &function, const Q
return true;
}
//-- \subsection{setTimer(function, milliseconds[, object])}
//-- Set a function to run repeated at some given time interval. The function to run
//-- is the first parameter, and it \underline{must be quoted}, otherwise the function will
//-- be inlined. The second parameter is the interval, in milliseconds. A third, optional
//-- parameter can be a game object to pass to the timer function. If the game object
//-- dies, the timer stops running. The minimum number of milliseconds is 100, but such
//-- fast timers are strongly discouraged as they may deteriorate the game performance.
//--
//-- \begin{lstlisting}
//-- function conDroids()
//-- {
//-- ... do stuff ...
//-- }
//-- // call conDroids every 4 seconds
//-- setTimer("conDroids", 4000);
//-- \end{lstlisting}
static QScriptValue js_setTimer(QScriptContext *context, QScriptEngine *engine)
{
QString funcName = context->argument(0).toString();
QScriptValue ms = context->argument(1);
int player = engine->globalObject().property("me").toInt32();
timerNode node(engine, funcName, player, ms.toInt32());
if (context->argumentCount() == 3)
{
QScriptValue obj = context->argument(2);
node.baseobj = obj.property("id").toInt32();
}
node.type = TIMER_REPEAT;
timers.push_back(node);
return QScriptValue();
}
//-- \subsection{removeTimer(function)}
//-- Removes an existing timer. The first parameter is the function timer to remove,
//-- and its name \underline{must be quoted}.
static QScriptValue js_removeTimer(QScriptContext *context, QScriptEngine *engine)
{
QString function = context->argument(0).toString();
@ -132,29 +168,13 @@ static QScriptValue js_removeTimer(QScriptContext *context, QScriptEngine *engin
return QScriptValue();
}
/// Special scripting function that registers a timer event. Note: Functions must be passed
/// quoted, otherwise they will be inlined! If a third parameter is passed, this must be an
/// object, which is then passed to the timer. If the object is dead, the timer stops.
static QScriptValue js_setTimer(QScriptContext *context, QScriptEngine *engine)
{
QString funcName = context->argument(0).toString();
QScriptValue ms = context->argument(1);
int player = engine->globalObject().property("me").toInt32();
timerNode node(engine, funcName, player, ms.toInt32());
if (context->argumentCount() == 3)
{
QScriptValue obj = context->argument(2);
node.baseobj = obj.property("id").toInt32();
}
node.type = TIMER_REPEAT;
timers.push_back(node);
return QScriptValue();
}
/// Special scripting function that queues up a function to call once at a later time frame.
/// Note: Functions must be passed quoted, otherwise they will be inlined! If a third
/// parameter is passed, this must be an object, which is then passed to the timer. If
/// the object is dead, the timer stops.
//-- \subsection{queue(function[, object])}
//-- Queues up a function to run at a later game frame. This is useful to prevent
//-- stuttering during the game, which can happen if too much script processing is
//-- done at once. The function to run is the first parameter, and it
//-- \underline{must be quoted}, otherwise the function will be inlined. A second, optional
//-- parameter can be a game object to pass to the queued function. If the game object
//-- dies before the queued call runs, nothing happens.
static QScriptValue js_queue(QScriptContext *context, QScriptEngine *engine)
{
QString funcName = context->argument(0).toString();
@ -193,10 +213,13 @@ void scriptRemoveObject(const BASE_OBJECT *psObj)
}
}
/// Special scripting function that binds a function call to an object. The function
/// is called before the object is destroyed.
/// Note: Functions must be passed quoted, otherwise they will be inlined! If a third
/// parameter is passed, this must be a player, which may be used for filtering.
//-- \subsection{bind(function, object[, player])}
//-- Bind a function call to an object. The function is called before the
//-- object is destroyed. The function to run is the first parameter, and it
//-- \underline{must be quoted}, otherwise the function will be inlined. The
//-- second argument is the object to bind to. A third, optional player parameter
//-- may be passed, which may be used for filtering, depending on the object type.
//-- \emph{NOTE: This function is under construction and is subject to total change!}
static QScriptValue js_bind(QScriptContext *context, QScriptEngine *engine)
{
bindNode node;
@ -222,7 +245,9 @@ static QScriptValue js_bind(QScriptContext *context, QScriptEngine *engine)
return QScriptValue();
}
// Currently breaks the lint test, so use with care
//-- \subsection{include(file)}
//-- Includes another source code file at this point. This is experimental, and breaks the
//-- lint tool, so use with care.
static QScriptValue js_include(QScriptContext *context, QScriptEngine *engine)
{
QString path = context->argument(0).toString();
@ -357,16 +382,31 @@ bool loadPlayerScript(QString path, int player, int difficulty)
engine->globalObject().setProperty("bind", engine->newFunction(js_bind));
// Special global variables
//== \item[me] The player the script is currently running as.
engine->globalObject().setProperty("me", player, QScriptValue::ReadOnly | QScriptValue::Undeletable);
//== \item[selectedPlayer] The player ontrolled by the client on which the script runs.
engine->globalObject().setProperty("selectedPlayer", selectedPlayer, QScriptValue::ReadOnly | QScriptValue::Undeletable);
//== \item[gameTime] The current game time. Updated before every invokation of a script.
engine->globalObject().setProperty("gameTime", gameTime, QScriptValue::ReadOnly | QScriptValue::Undeletable);
//== \item[difficulty] The currently set campaign difficulty, or the current AI's difficulty setting. It will be one of
//== EASY, MEDIUM, HARD or INSANE.
engine->globalObject().setProperty("difficulty", difficulty, QScriptValue::ReadOnly | QScriptValue::Undeletable);
//== \item[mapName] The name of the current map.
engine->globalObject().setProperty("mapName", game.map, QScriptValue::ReadOnly | QScriptValue::Undeletable);
//== \item[baseType] The type of base that the game starts with. It will be one of CAMP_CLEAN, CAMP_BASE or CAMP_WALLS.
engine->globalObject().setProperty("baseType", game.base, QScriptValue::ReadOnly | QScriptValue::Undeletable);
//== \item[alliancesType] The type of alliances permitted in this game. It will be one of NO_ALLIANCES, ALLIANCES or ALLIANCES_TEAMS.
engine->globalObject().setProperty("alliancesType", game.alliance, QScriptValue::ReadOnly | QScriptValue::Undeletable);
//== \item[powerType] The power level set for this game.
engine->globalObject().setProperty("powerType", game.power, QScriptValue::ReadOnly | QScriptValue::Undeletable);
//== \item[maxPlayers] The number of active players in this game.
engine->globalObject().setProperty("maxPlayers", game.maxPlayers, QScriptValue::ReadOnly | QScriptValue::Undeletable);
//== \item[scavengers] Whether or not scavengers are activated in this game.
engine->globalObject().setProperty("scavengers", game.scavengers, QScriptValue::ReadOnly | QScriptValue::Undeletable);
//== \item[mapWidth] Width of map in tiles.
engine->globalObject().setProperty("mapWidth", mapWidth, QScriptValue::ReadOnly | QScriptValue::Undeletable);
//== \item[mapHeight] Height of map in tiles.
engine->globalObject().setProperty("mapHeight", mapHeight, QScriptValue::ReadOnly | QScriptValue::Undeletable);
// Regular functions
registerFunctions(engine);

View File

@ -283,6 +283,11 @@ bool writeLabels(const char *filename)
//
// All script functions should be prefixed with "js_" then followed by same name as in script.
//-- \subsection{label(key)}
//-- Fetch something denoted by a label. Labels are areas, positions or game objects on
//-- the map defined using the map editor and stored together with the map. The only argument
//-- is a text label. The function returns a composite object that has a type variable
//-- defining what it is (in case this is unclear).
static QScriptValue js_label(QScriptContext *context, QScriptEngine *engine)
{
QString label = context->argument(0).toString();
@ -347,7 +352,11 @@ static QScriptValue js_newGroup(QScriptContext *, QScriptEngine *)
return QScriptValue(newGrp->id);
}
// TODO, allow passing in a research object instead of a string as second parameter
//-- \subsection{pursueResearch(lab, research)}
//-- Start researching the first available technology on the way to the given technology.
//-- First parameter is the structure to research in, which must be a research lab. The
//-- second parameter is the technology to pursue, as a text string as defined in "research.txt".
// TODO, allow passing in a research object or string array instead of a string as second parameter
static QScriptValue js_pursueResearch(QScriptContext *context, QScriptEngine *engine)
{
QScriptValue structVal = context->argument(0);
@ -414,6 +423,10 @@ static QScriptValue js_pursueResearch(QScriptContext *context, QScriptEngine *en
return QScriptValue(false); // none found
}
//-- \subsection{getResearch(research)}
//-- Fetch information about a given technology item, given by a string that matches
//-- its definition in "research.txt". The resulting object is composed of the following
//-- variables: power (int), points (int), started (bool), done (bool), and name (string).
static QScriptValue js_getResearch(QScriptContext *context, QScriptEngine *engine)
{
int player = engine->globalObject().property("me").toInt32();
@ -423,6 +436,9 @@ static QScriptValue js_getResearch(QScriptContext *context, QScriptEngine *engin
return convResearch(psResearch, engine, player);
}
//-- \subsection{enumResearch()}
//-- Returns an array of all research items that are currently and immediately available for research.
//-- These items are composite objects, as returned by \emph{getResearch}.
static QScriptValue js_enumResearch(QScriptContext *context, QScriptEngine *engine)
{
QList<RESEARCH *> reslist;
@ -443,6 +459,8 @@ static QScriptValue js_enumResearch(QScriptContext *context, QScriptEngine *engi
return result;
}
//-- \subsection{componentAvailable(component type, component name)}
//-- Checks whether a given component is available to the current player.
static QScriptValue js_componentAvailable(QScriptContext *context, QScriptEngine *engine)
{
int player = engine->globalObject().property("me").toInt32();
@ -454,6 +472,9 @@ static QScriptValue js_componentAvailable(QScriptContext *context, QScriptEngine
return QScriptValue(avail);
}
//-- \subsection{getTemplate(template name)}
//-- Return a descriptive object for the given template. Returns null if template
//-- does not exist.
static QScriptValue js_getTemplate(QScriptContext *context, QScriptEngine *engine)
{
int player = engine->globalObject().property("me").toInt32();
@ -473,7 +494,9 @@ static QScriptValue js_getTemplate(QScriptContext *context, QScriptEngine *engin
return QScriptValue();
}
// newTemplate(name, body, propulsion, reserved, turrets...)
//-- \subsection{newTemplate(name, body, propulsion, reserved, turrets...)}
//-- Generate a new template with the given name, body, propulsion and turrets.
//-- The reserved parameter should be passed an empty string for now.
static QScriptValue js_newTemplate(QScriptContext *context, QScriptEngine *engine)
{
int player = engine->globalObject().property("me").toInt32();
@ -556,6 +579,12 @@ static QScriptValue js_newTemplate(QScriptContext *context, QScriptEngine *engin
return QScriptValue(valid);
}
//-- \subsection{enumStruct([player[, structure type[, looking player]]])}
//-- Returns an array of structure objects. If no parameters given, it will
//-- return all of the structures for the current player. The second parameter
//-- is the name of the structure type, as defined in "structures.txt". The
//-- third parameter can be used to filter by visibility, the default is not
//-- to filter.
static QScriptValue js_enumStruct(QScriptContext *context, QScriptEngine *engine)
{
QList<STRUCTURE *> matches;
@ -1366,18 +1395,26 @@ bool registerFunctions(QScriptEngine *engine)
engine->globalObject().setProperty("removeStruct", engine->newFunction(js_removeStruct));
// Set some useful constants
//__ \item[DORDER_ATTACK] Order a droid to attack something.
engine->globalObject().setProperty("DORDER_ATTACK", DORDER_ATTACK, QScriptValue::ReadOnly | QScriptValue::Undeletable);
//__ \item[DORDER_MOVE] Order a droid to move somewhere.
engine->globalObject().setProperty("DORDER_MOVE", DORDER_MOVE, QScriptValue::ReadOnly | QScriptValue::Undeletable);
//__ \item[DORDER_SCOUT] Order a droid to move somewhere and stop to attack anything on the way.
engine->globalObject().setProperty("DORDER_SCOUT", DORDER_SCOUT, QScriptValue::ReadOnly | QScriptValue::Undeletable);
//__ \item[DORDER_BUILD] Order a droid to build something.
engine->globalObject().setProperty("DORDER_BUILD", DORDER_BUILD, QScriptValue::ReadOnly | QScriptValue::Undeletable);
//__ \item[DORDER_HELPBUILD] Order a droid to help build something.
engine->globalObject().setProperty("DORDER_HELPBUILD", DORDER_HELPBUILD, QScriptValue::ReadOnly | QScriptValue::Undeletable);
//__ \item[DORDER_LINEBUILD] Order a droid to build something repeatedly in a line.
engine->globalObject().setProperty("DORDER_LINEBUILD", DORDER_LINEBUILD, QScriptValue::ReadOnly | QScriptValue::Undeletable);
//__ \item[DORDER_REPAIR] Order a droid to repair something.
engine->globalObject().setProperty("DORDER_REPAIR", DORDER_REPAIR, QScriptValue::ReadOnly | QScriptValue::Undeletable);
//__ \item[DORDER_RETREAT] Order a droid to retreat back to HQ.
engine->globalObject().setProperty("DORDER_RETREAT", DORDER_RETREAT, QScriptValue::ReadOnly | QScriptValue::Undeletable);
//__ \item[DORDER_PATROL] Order a droid to patrol.
engine->globalObject().setProperty("DORDER_PATROL", DORDER_PATROL, QScriptValue::ReadOnly | QScriptValue::Undeletable);
//__ \item[DORDER_BUILDMODULE] Order a droid to build a module.
engine->globalObject().setProperty("DORDER_BUILDMODULE", DORDER_BUILDMODULE, QScriptValue::ReadOnly | QScriptValue::Undeletable);
engine->globalObject().setProperty("mapWidth", mapWidth, QScriptValue::ReadOnly | QScriptValue::Undeletable);
engine->globalObject().setProperty("mapHeight", mapHeight, QScriptValue::ReadOnly | QScriptValue::Undeletable);
engine->globalObject().setProperty("COMMAND", IDRET_COMMAND, QScriptValue::ReadOnly | QScriptValue::Undeletable);
engine->globalObject().setProperty("OPTIONS", IDRET_COMMAND, QScriptValue::ReadOnly | QScriptValue::Undeletable);
engine->globalObject().setProperty("BUILD", IDRET_BUILD, QScriptValue::ReadOnly | QScriptValue::Undeletable);
@ -1416,6 +1453,8 @@ bool registerFunctions(QScriptEngine *engine)
engine->globalObject().setProperty("INSANE", DIFFICULTY_INSANE, QScriptValue::ReadOnly | QScriptValue::Undeletable);
// Static knowledge about players
//== \item[playerData] An array of information about the players in a game. Each item in the array is an object
//== containing the following variables: difficulty (see \emph{difficulty} global constant), colour, position, and team.
QScriptValue playerData = engine->newArray(game.maxPlayers);
for (int i = 0; i < game.maxPlayers; i++)
{
@ -1429,6 +1468,10 @@ bool registerFunctions(QScriptEngine *engine)
engine->globalObject().setProperty("playerData", playerData, QScriptValue::ReadOnly | QScriptValue::Undeletable);
// Static map knowledge about start positions
//== \item[derrickPositions] An array of derrick starting positions on the current map. Each item in the array is an
//== object containing the x and y variables for a derrick.
//== \item[startPositions] An array of player start positions on the current map. Each item in the array is an
//== object containing the x and y variables for a player start position.
QScriptValue startPositions = engine->newArray(game.maxPlayers);
for (int i = 0; i < game.maxPlayers; i++)
{