Re #132 (dual threaded race engine) : First try implementation, inhibitable through Options/Simulation menu (not tested network; movie capture mode still to fix ; some sticky collision sound to fix ; ...)

git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@2522 30fe4595-0a0c-4342-8851-515496e4dcbd

Former-commit-id: 69bcdd1891aa99e73f429421423954f185bbaa0a
Former-commit-id: 29c8e51ec595846142085ce77ae6df6debf8ca09
This commit is contained in:
pouillot 2010-06-13 09:45:25 +00:00
parent 1127e3e6e6
commit 01f7254887
13 changed files with 1153 additions and 117 deletions

View file

@ -288,6 +288,10 @@ typedef struct tCollisionState_ {
sgVec3 pos;
sgVec3 force;
} tCollisionState;
/* structure access */
#define _collCount priv.collision_state.collision_count
#define _collPos priv.collision_state.pos
#define _collForce priv.collision_state.force
typedef struct MemoryPoolItem tMemoryPoolItem;
typedef tMemoryPoolItem* tMemoryPool;
@ -328,10 +332,10 @@ typedef struct {
int collision;
float smoke;
t3Dd normal;
t3Dd collpos; /**< Collision position, useful for sound*/
t3Dd collpos; /**< Collision position, useful for sound ; Simu V2 only */
int dammage;
int debug;
tCollisionState collision_state; /**< collision state */
tCollisionState collision_state; /**< collision state ; Simu V3 only */
tMemPoolCar memoryPool;
tdble driveSkill; /**< Skill level for robots: 0.0 means as fast as possible; 10.0 means at a slower speed so players can easier win */
} tPrivCar;
@ -360,8 +364,12 @@ typedef struct {
#define _reaction priv.reaction
#define _dammage priv.dammage
#define _driveSkill priv.driveSkill
#define _collision priv.collision
#define _smoke priv.smoke
#define _normal priv.normal
#define _coll2Pos priv.collpos
#define _newTrackMemPool priv.memoryPool.shutdown
#define _newTrackMemPool priv.memoryPool.newTrack
#define _newRaceMemPool priv.memoryPool.newRace
#define _endRaceMemPool priv.memoryPool.endRace
#define _shutdownMemPool priv.memoryPool.shutdown

View file

@ -35,6 +35,9 @@
#define RCM_IDENT 0
// Comment-out to inhibit multi-threaded race engine (get back to old nearly unmodified code).
#define ReMultiThreaded 1
struct RmInfo;
typedef int (*tfRmRunState) (struct RmInfo *);
@ -158,11 +161,17 @@ typedef struct
#define RM_DISP_MODE_SIMU_SIMU 3
int displayMode;
int refreshDisplay;
#ifdef ReMultiThreaded
tCarElt *inPitMenuCar;
char *message;
double messageEnd;
char *bigMessage;
double bigMessageEnd;
#endif
} tRaceEngineInfo;
#define _reState raceEngineInfo.state
#define _reParam raceEngineInfo.param
#define _reRacemanItf raceEngineInfo.itf.racemanItf
#define _reTrackItf raceEngineInfo.itf.trackItf
#define _reGraphicItf raceEngineInfo.itf.graphicItf
#define _reSimItf raceEngineInfo.itf.simItf
@ -178,6 +187,13 @@ typedef struct
#define _reLastTime raceEngineInfo.lastTime
#define _displayMode raceEngineInfo.displayMode
#define _refreshDisplay raceEngineInfo.refreshDisplay
#ifdef ReMultiThreaded
# define _reInPitMenuCar raceEngineInfo.inPitMenuCar
# define _reMessage raceEngineInfo.message
# define _reMessageEnd raceEngineInfo.messageEnd
# define _reBigMessage raceEngineInfo.bigMessage
# define _reBigMessageEnd raceEngineInfo.bigMessageEnd
#endif
#define RM_PNST_DRIVETHROUGH 0x00000001
#define RM_PNST_STOPANDGO 0x00000002
@ -323,13 +339,16 @@ typedef struct RmInfo
#define RM_VAL_INVISIBLE "results only"
#define RM_VAL_SIMUSIMU "simulation simulation"
/* Movie capture */
#define RM_SECT_MOVIE_CAPTURE "Movie Capture"
#define RM_ATT_CAPTURE_ENABLE "enable capture"
#define RM_ATT_CAPTURE_FPS "fps"
#define RM_ATT_CAPTURE_OUT_DIR "output directory"
#define RM_SECT_SUBFILES "Header/Subfiles"
#define RM_ATTR_HASSUBFILES "has subfiles"
#define RM_ATTR_FIRSTSUBFILE "first subfile"
#define RM_ATTR_SUFFIX "suffix"
@ -339,6 +358,7 @@ typedef struct RmInfo
#define RM_ATTR_PREVSUBFILE "prev subfile"
#define RM_ATTR_RESULTSUBFILE "result subfile"
#define RM_ATTR_SUBFILE "subfile"
#define RM_SECT_ENDOFSEASON "End-Of-Season"
#define RM_SECT_ENDOFSEASON_CLASSPOINTS "End-Of-Season/Class Points"
@ -346,7 +366,30 @@ typedef struct RmInfo
#define RM_SECT_LASTNAME "Names/Last Name"
#define RM_SECT_DRIVERINFO "Driver Info"
/* RESULTS */
/* Race Engine modules */
#define RM_SECT_MODULES "Modules"
#define RM_ATTR_MOD_TRACK "track"
#define RM_ATTR_MOD_SIMU "simu"
#define RM_ATTR_MOD_GRAPHIC "graphic"
#define RM_VAL_MOD_SIMU_V2 "simuv2"
#define RM_VAL_MOD_SIMU_V3 "simuv3"
#define RM_VAL_MOD_TRACK "track"
#define RM_VAL_MOD_SSGRAPH "ssggraph"
/* Race Engine itself */
#define RM_SECT_RACE_ENGINE "Race Engine"
#define RM_ATTR_MULTI_THREADING "multi-threading"
#define RM_VAL_AUTO "auto"
#define RM_VAL_ON "on"
#define RM_VAL_OFF "off"
/* Results */
#define RE_SECT_HEADER "Header"
#define RE_ATTR_DATE "date"

View file

@ -22,92 +22,123 @@
@version $Id: simuconfig.cpp,v 1.4 2006/10/06 20:44:51 berniw Exp $
*/
#include <stdio.h>
#include <stdlib.h>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <raceman.h>
#include <portability.h>
#include <tgfclient.h>
#include <raceinit.h>
#include "simuconfig.h"
#include <portability.h>
#include "gui.h"
/* list of available simulation engine */
static const char *simuVersionList[] = {"simuv2", "simuv3"};
static const int nbVersions = sizeof(simuVersionList) / sizeof(simuVersionList[0]);
static int curVersion = 0;
/* gui label id */
/* list of available simulation engine */
static const char *SimuVersionList[] = {RM_VAL_MOD_SIMU_V2, RM_VAL_MOD_SIMU_V3};
static const int NbSimuVersions = sizeof(SimuVersionList) / sizeof(SimuVersionList[0]);
static int CurSimuVersion = 0;
/* list of available multi-threading schemes */
static const char *MultiThreadSchemeList[] = {RM_VAL_AUTO, RM_VAL_ON, RM_VAL_OFF};
static const int NbMultiThreadSchemes = sizeof(MultiThreadSchemeList) / sizeof(MultiThreadSchemeList[0]);
#ifdef ReMultiThreaded
static int CurMultiThreadScheme = 0;
#else
static int CurMultiThreadScheme = 2;
#endif
/* gui label ids */
static int SimuVersionId;
static int MultiThreadSchemeId;
/* gui screen handles */
static void *scrHandle = NULL;
static void *prevHandle = NULL;
static void *ScrHandle = NULL;
static void *PrevScrHandle = NULL;
static void ReadSimuCfg(void)
static void loadSimuCfg(void)
{
const char *versionName;
const char *simuVersionName;
const char *multiThreadSchemeName;
int i;
char buf[1024];
snprintf(buf, 1024, "%s%s", GetLocalDir(), RACE_ENG_CFG);
void *paramHandle = GfParmReadFile(buf, GFPARM_RMODE_REREAD | GFPARM_RMODE_CREAT);
versionName = GfParmGetStr(paramHandle, "Modules", "simu", simuVersionList[0]);
for (i = 0; i < nbVersions; i++) {
if (strcmp(versionName, simuVersionList[i]) == 0) {
curVersion = i;
simuVersionName = GfParmGetStr(paramHandle, RM_SECT_MODULES, RM_ATTR_MOD_SIMU, SimuVersionList[0]);
for (i = 0; i < NbSimuVersions; i++) {
if (strcmp(simuVersionName, SimuVersionList[i]) == 0) {
CurSimuVersion = i;
break;
}
}
#ifdef ReMultiThreaded
multiThreadSchemeName = GfParmGetStr(paramHandle, RM_SECT_RACE_ENGINE, RM_ATTR_MULTI_THREADING, MultiThreadSchemeList[0]);
for (i = 0; i < NbMultiThreadSchemes; i++) {
if (strcmp(multiThreadSchemeName, MultiThreadSchemeList[i]) == 0) {
CurMultiThreadScheme = i;
break;
}
}
#endif
GfParmReleaseHandle(paramHandle);
GfuiLabelSetText(scrHandle, SimuVersionId, simuVersionList[curVersion]);
GfuiLabelSetText(ScrHandle, SimuVersionId, SimuVersionList[CurSimuVersion]);
GfuiLabelSetText(ScrHandle, MultiThreadSchemeId, MultiThreadSchemeList[CurMultiThreadScheme]);
}
/* Save the choosen values in the corresponding parameter file */
static void SaveSimuVersion(void * /* dummy */)
static void storeSimuCfg(void * /* dummy */)
{
char buf[1024];
snprintf(buf, 1024, "%s%s", GetLocalDir(), RACE_ENG_CFG);
void *paramHandle = GfParmReadFile(buf, GFPARM_RMODE_REREAD | GFPARM_RMODE_CREAT);
GfParmSetStr(paramHandle, "Modules", "simu", simuVersionList[curVersion]);
GfParmSetStr(paramHandle, RM_SECT_MODULES, RM_ATTR_MOD_SIMU, SimuVersionList[CurSimuVersion]);
GfParmSetStr(paramHandle, RM_SECT_RACE_ENGINE, RM_ATTR_MULTI_THREADING, MultiThreadSchemeList[CurMultiThreadScheme]);
GfParmWriteFile(NULL, paramHandle, "raceengine");
GfParmReleaseHandle(paramHandle);
/* return to previous screen */
GfuiScreenActivate(prevHandle);
GfuiScreenActivate(PrevScrHandle);
return;
}
/* change the simulation version */
static void
ChangeSimuVersion(void *vp)
onChangeSimuVersion(void *vp)
{
if (vp == 0) {
curVersion--;
if (curVersion < 0) {
curVersion = nbVersions - 1;
}
} else {
curVersion++;
if (curVersion == nbVersions) {
curVersion = 0;
}
}
GfuiLabelSetText(scrHandle, SimuVersionId, simuVersionList[curVersion]);
CurSimuVersion = (CurSimuVersion + NbSimuVersions + (int)(long)vp) % NbSimuVersions;
GfuiLabelSetText(ScrHandle, SimuVersionId, SimuVersionList[CurSimuVersion]);
}
/* change the multi-threading scheme */
static void
onChangeMultiThreadScheme(void *vp)
{
CurMultiThreadScheme =
(CurMultiThreadScheme + NbMultiThreadSchemes + (int)(long)vp) % NbMultiThreadSchemes;
GfuiLabelSetText(ScrHandle, MultiThreadSchemeId, MultiThreadSchemeList[CurMultiThreadScheme]);
}
static void onActivate(void * /* dummy */)
{
ReadSimuCfg();
loadSimuCfg();
}
@ -116,32 +147,43 @@ void *
SimuMenuInit(void *prevMenu)
{
/* screen already created */
if (scrHandle) {
return scrHandle;
if (ScrHandle) {
return ScrHandle;
}
prevHandle = prevMenu;
PrevScrHandle = prevMenu;
scrHandle = GfuiScreenCreateEx((float*)NULL, NULL, onActivate, NULL, (tfuiCallback)NULL, 1);
ScrHandle = GfuiScreenCreateEx((float*)NULL, NULL, onActivate, NULL, (tfuiCallback)NULL, 1);
void *param = LoadMenuXML("simulationmenu.xml");
CreateStaticControls(param,scrHandle);
void *menuDescHdle = LoadMenuXML("simulationmenu.xml");
CreateStaticControls(menuDescHdle, ScrHandle);
CreateButtonControl(scrHandle,param,"simvleftarrow",(void*)-1,ChangeSimuVersion);
CreateButtonControl(scrHandle,param,"simvrightarrow",(void*)1,ChangeSimuVersion);
SimuVersionId = CreateLabelControl(ScrHandle,menuDescHdle,"simulabel");
CreateButtonControl(ScrHandle, menuDescHdle, "simuleftarrow", (void*)-1, onChangeSimuVersion);
CreateButtonControl(ScrHandle, menuDescHdle, "simurightarrow", (void*)1, onChangeSimuVersion);
SimuVersionId = CreateLabelControl(scrHandle,param,"simulabel");
CreateButtonControl(scrHandle,param,"accept",prevMenu,SaveSimuVersion);
CreateButtonControl(scrHandle,param,"cancel",prevMenu,GfuiScreenActivate);
MultiThreadSchemeId = CreateLabelControl(ScrHandle, menuDescHdle, "mthreadlabel");
#ifdef ReMultiThreaded
CreateButtonControl(ScrHandle, menuDescHdle, "mthreadleftarrow", (void*)-1, onChangeMultiThreadScheme);
CreateButtonControl(ScrHandle, menuDescHdle, "mthreadrightarrow", (void*)1, onChangeMultiThreadScheme);
#endif
CreateButtonControl(ScrHandle, menuDescHdle, "accept", PrevScrHandle, storeSimuCfg);
CreateButtonControl(ScrHandle, menuDescHdle, "cancel", PrevScrHandle, GfuiScreenActivate);
GfParmReleaseHandle(param);
GfParmReleaseHandle(menuDescHdle);
GfuiAddKey(scrHandle, GFUIK_RETURN, "Save", NULL, SaveSimuVersion, NULL);
GfuiAddKey(scrHandle, GFUIK_ESCAPE, "Cancel Selection", prevMenu, GfuiScreenActivate, NULL);
GfuiAddKey(scrHandle, GFUIK_F1, "Help", scrHandle, GfuiHelpScreen, NULL);
GfuiAddKey(scrHandle, GFUIK_F12, "Screen-Shot", NULL, GfuiScreenShot, NULL);
GfuiAddKey(scrHandle, GFUIK_LEFT, "Previous Option in list", (void*)0, ChangeSimuVersion, NULL);
GfuiAddKey(scrHandle, GFUIK_RIGHT, "Next Option in list", (void*)1, ChangeSimuVersion, NULL);
GfuiAddKey(ScrHandle, GFUIK_RETURN, "Save", NULL, storeSimuCfg, NULL);
GfuiAddKey(ScrHandle, GFUIK_ESCAPE, "Cancel Selection", PrevScrHandle, GfuiScreenActivate, NULL);
GfuiAddKey(ScrHandle, GFUIK_F1, "Help", ScrHandle, GfuiHelpScreen, NULL);
GfuiAddKey(ScrHandle, GFUIK_F12, "Screen-Shot", NULL, GfuiScreenShot, NULL);
GfuiAddKey(ScrHandle, GFUIK_LEFT, "Previous simu engine version", (void*)-1, onChangeSimuVersion, NULL);
GfuiAddKey(ScrHandle, GFUIK_RIGHT, "Next simu engine version", (void*)1, onChangeSimuVersion, NULL);
#ifdef ReMultiThreaded
GfuiAddKey(ScrHandle, GFUIK_UP, "Previous multi-threading scheme", (void*)-1, onChangeMultiThreadScheme, NULL);
GfuiAddKey(ScrHandle, GFUIK_DOWN, "Next multi-threading scheme", (void*)1, onChangeMultiThreadScheme, NULL);
#endif
return scrHandle;
return ScrHandle;
}

File diff suppressed because it is too large Load diff

View file

@ -26,7 +26,11 @@
#ifndef _RACEENGINE_H_
#define _RACEENGINE_H_
#ifdef ReMultiThreaded
extern void ReInitUpdater();
extern void ReInitCarGraphics();
extern void ReShutdownUpdater();
#endif // ReMultiThreaded
extern void ReStart(void);
extern void ReStop(void);

View file

@ -2,7 +2,7 @@
<!--
file : raceengine.xml
created : Sat Nov 16 19:39:26 CET 2002
copyright : (C) 2002 by Eric Espié
copyright : (C) 2002 by Eric Espi<EFBFBD>
email : Eric.Espie@torcs.org
version : $Id: raceengine.xml,v 1.5 2005/02/01 15:55:52 berniw Exp $
-->
@ -14,7 +14,7 @@
<!DOCTYPE params SYSTEM "../tgf/params.dtd">
<params name="" type="template" mode="mw">
<params name="" type="template" mode="mw" version="1.1">
<section name="Modules">
<attstr name="track" val="track"/>
@ -28,6 +28,10 @@
<attstr name="output directory" val="/home/torcs/captures"/>
</section>
<section name="Race Engine">
<attstr name="multi-threading" in="auto,on,off" val="off"/>
</section>
</params>

View file

@ -2,7 +2,7 @@
file : racegl.cpp
created : Sat Nov 16 18:22:00 CET 2002
copyright : (C) 2002 by Eric Espié
copyright : (C) 2002 by Eric Espi<EFBFBD>
email : eric.espie@torcs.org
version : $Id: racegl.cpp,v 1.7 20 Mar 2006 04:30:18 olethros Exp $
@ -70,9 +70,11 @@ reScreenActivate(void * /* dummy */)
GfelSetDisplayCB(reDisplay);
// Resync race engine if it is not paused or stopped
if ((ReInfo->s->_raceState & RM_RACE_PAUSED) == 0) {
ReStart(); /* resynchro */
}
GfelPostRedisplay();
}
@ -80,11 +82,15 @@ static void
ReBoardInfo(void * /* vboard */)
{
if (ReInfo->s->_raceState & RM_RACE_PAUSED) {
#ifndef ReMultiThreaded
ReInfo->s->_raceState &= ~RM_RACE_PAUSED;
#endif
ReStart();
GfuiVisibilitySet(reScreenHandle, rePauseId, 0);
} else {
#ifndef ReMultiThreaded
ReInfo->s->_raceState |= RM_RACE_PAUSED;
#endif
ReStop();
GfuiVisibilitySet(reScreenHandle, rePauseId, 1);
}
@ -102,7 +108,7 @@ reSkipPreStart(void * /* dummy */)
static void
reMovieCapture(void * /* dummy */)
{
tRmMovieCapture *capture = &(ReInfo->movieCapture);
tRmMovieCapture *capture = &(ReInfo->movieCapture);
if (!capture->enabled || ReInfo->_displayMode == RM_DISP_MODE_NONE || ReInfo->_displayMode == RM_DISP_MODE_SIMU_SIMU)
{
@ -157,13 +163,21 @@ ReSetRaceMsg(const char *msg)
{
static char *curMsg = 0;
if (curMsg) free(curMsg);
#ifdef ReMultiThreaded
// If nothing to change, don't change anything.
if ((!curMsg && !msg) || (curMsg && msg && !strcmp(curMsg, msg)))
return;
#endif
// Otherwise, set the new text for the label.
if (curMsg)
free(curMsg);
if (msg) {
curMsg = strdup(msg);
GfuiLabelSetText(reScreenHandle, reMsgId, curMsg);
curMsg = strdup(msg);
GfuiLabelSetText(reScreenHandle, reMsgId, curMsg);
} else {
curMsg = 0;
GfuiLabelSetText(reScreenHandle, reMsgId, "");
curMsg = 0;
GfuiLabelSetText(reScreenHandle, reMsgId, "");
}
}
@ -172,13 +186,20 @@ ReSetRaceBigMsg(const char *msg)
{
static char *curMsg = 0;
if (curMsg) free(curMsg);
#ifdef ReMultiThreaded
// If nothing to change, don't change anything.
if ((!curMsg && !msg) || (curMsg && msg && !strcmp(curMsg, msg)))
return;
#endif
if (curMsg)
free(curMsg);
if (msg) {
curMsg = strdup(msg);
GfuiLabelSetText(reScreenHandle, reBigMsgId, curMsg);
curMsg = strdup(msg);
GfuiLabelSetText(reScreenHandle, reBigMsgId, curMsg);
} else {
curMsg = 0;
GfuiLabelSetText(reScreenHandle, reBigMsgId, "");
curMsg = 0;
GfuiLabelSetText(reScreenHandle, reBigMsgId, "");
}
}

View file

@ -850,10 +850,6 @@ reDumpTrack(tTrack *track, int verbose)
sprintf(buf, " by %s (%.2f m long, %.2f m wide) ...",
track->author, track->length, track->width);
RmLoadingScreenSetText(buf);
sprintf(buf, ">>> Track Length %.2f m", track->length);
RmLoadingScreenSetText(buf);
sprintf(buf, ">>> Track Width %.2f m", track->width);
RmLoadingScreenSetText(buf);
GfOut("++++++++++++ Track ++++++++++++\n");
GfOut("Name = %s\n", track->name);

View file

@ -105,6 +105,10 @@ AbortRaceHookActivate(void * /* dummy */)
{
GfuiScreenActivate(ReInfo->_reGameScreen);
#ifdef ReMultiThreaded
ReShutdownUpdater();
#endif
ReInfo->_reSimItf.shutdown();
if (ReInfo->_displayMode == RM_DISP_MODE_NORMAL) {
if (ReInfo->_reGraphicItf.shutdowncars)
@ -120,8 +124,8 @@ AbortRaceHookActivate(void * /* dummy */)
GetNetwork()->Disconnect();
}
FREEZ(ReInfo->_reCarInfo);
/* Return to race menu */
if (ReInfo->params != ReInfo->mainParams)
{
@ -428,9 +432,23 @@ reRaceRealStart(void)
if (ReInfo->_reGraphicItf.initview)
ReInfo->_reGraphicItf.initview((sw-vw)/2, (sh-vh)/2, vw, vh, GR_VIEW_STD, ReInfo->_reGameScreen);
#ifdef ReMultiThreaded
ReInfo->_reInPitMenuCar = 0;
ReInfo->_reMessage = 0;
ReInfo->_reMessageEnd = 0.0;
ReInfo->_reBigMessage = 0;
ReInfo->_reBigMessageEnd = 0.0;
ReInitUpdater();
#endif
if (ReInfo->_displayMode == RM_DISP_MODE_NORMAL) {
RmLoadingScreenSetText("Loading cars ...");
#ifdef ReMultiThreaded
ReInitCarGraphics();
#else
ReInfo->_reGraphicItf.initcars(s); /* At this stage, the graphical module must be already loaded */
#endif
}
RmLoadingScreenSetText("Ready.");
@ -576,6 +594,9 @@ static void
BackToRaceHookActivate(void * /* dummy */)
{
ReInfo->_reState = RE_STATE_RACE;
#ifdef ReMultiThreaded
ReInfo->s->_raceState &= ~RM_RACE_PAUSED;
#endif
GfuiScreenActivate(ReInfo->_reGameScreen);
}
@ -600,7 +621,13 @@ static void
RestartRaceHookActivate(void * /* dummy */)
{
ReRaceCleanup();
ReInfo->_reState = RE_STATE_PRE_RACE;
#ifdef ReMultiThreaded
ReInfo->s->_raceState &= ~RM_RACE_PAUSED;
#endif
GfuiScreenActivate(ReInfo->_reGameScreen);
}
@ -649,9 +676,13 @@ ReRaceStop(void)
{
void *params = ReInfo->params;
#ifdef ReMultiThreaded
ReStop();
#endif
if (!strcmp(GfParmGetStr(params, ReInfo->_reRaceName, RM_ATTR_ALLOW_RESTART, RM_VAL_NO), RM_VAL_NO))
{
if (!strcmp(GfParmGetStr(params, ReInfo->_reRaceName, RM_ATTR_MUST_COMPLETE, RM_VAL_YES), RM_VAL_YES) == 0)
if (strcmp(GfParmGetStr(params, ReInfo->_reRaceName, RM_ATTR_MUST_COMPLETE, RM_VAL_YES), RM_VAL_YES))
{
StopScrHandle = RmFourStateScreen("Race Stopped",
"Abandon Race", "Abort current race", AbortRaceHookInit(),
@ -667,7 +698,7 @@ ReRaceStop(void)
}
} else
{
if (!strcmp(GfParmGetStr(params, ReInfo->_reRaceName, RM_ATTR_MUST_COMPLETE, RM_VAL_YES), RM_VAL_YES)==0)
if (strcmp(GfParmGetStr(params, ReInfo->_reRaceName, RM_ATTR_MUST_COMPLETE, RM_VAL_YES), RM_VAL_YES))
{
StopScrHandle = RmFiveStateScreen("Race Stopped",
"Restart Race", "Restart the current race", RestartRaceHookInit(),
@ -694,6 +725,10 @@ ReRaceEnd(void)
void *params = ReInfo->params;
void *results = ReInfo->results;
#ifdef ReMultiThreaded
ReShutdownUpdater();
#endif
ReRaceCleanup();
if ((ReInfo->s->_raceType == RM_TYPE_QUALIF || ReInfo->s->_raceType == RM_TYPE_PRACTICE) && !(ReInfo->s->_features & RM_FEATURE_TIMEDSESSION))
@ -720,8 +755,6 @@ RePostRace(void)
void *results = ReInfo->results;
void *params = ReInfo->params;
//ReUpdateStandings();
curRaceIdx = (int)GfParmGetNum(results, RE_SECT_CURRENT, RE_ATTR_CUR_RACE, NULL, 1);
if (curRaceIdx < GfParmGetEltNb(params, RM_SECT_RACES)) {
curRaceIdx++;
@ -732,7 +765,9 @@ RePostRace(void)
}
ReUpdateStandings();
GfParmSetNum(results, RE_SECT_CURRENT, RE_ATTR_CUR_RACE, NULL, 1);
return RM_SYNC | RM_NEXT_STEP;
}

View file

@ -151,10 +151,10 @@ ReStateManage(void)
case RE_STATE_RACE:
mode = ReUpdate();
if (ReInfo->s->_raceState == RM_RACE_ENDED) {
/* race finished */
/* Race is finished */
ReInfo->_reState = RE_STATE_RACE_END;
} else if (mode & RM_END_RACE) {
/* interrupt by player */
/* Race was interrupted (paused) by the player */
ReInfo->_reState = RE_STATE_RACE_STOP;
}
@ -169,7 +169,7 @@ ReStateManage(void)
case RE_STATE_RACE_STOP:
GfOut("RaceEngine: state = RE_STATE_RACE_STOP\n");
/* Interrupted by player */
/* Race was interrupted (paused) by the player */
mode = ReRaceStop();
if (mode & RM_NEXT_STEP) {
ReInfo->_reState = RE_STATE_RACE_END;

View file

@ -22,6 +22,12 @@
#else
#include <sys/stat.h>
#include <sys/types.h>
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
#include <sys/param.h>
#include <sys/sysctl.h>
#else
#include <unistd.h>
#endif
#endif
#include <errno.h>
@ -746,3 +752,61 @@ int GfCreateDir(const char *path)
}
}
/* Get the actual number of CPUs / cores
TODO: Be careful about fake CPUs like those displayed by hyperthreaded processors ...
*/
int GfGetNumberOfCPUs()
{
int nCPUs = 0;
// Windows
#if defined(WIN32)
SYSTEM_INFO sysinfo;
GetSystemInfo(&sysinfo);
nCPUs = sysinfo.dwNumberOfProcessors;
// MacOS X, FreeBSD, OpenBSD, NetBSD, etc.:
#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
nt mib[4];
size_t len;
// Set the mib for hw.ncpu
// Get the number of CPUs from the system
// 1) Try HW_AVAILCPU first.
mib[0] = CTL_HW;
mib[1] = HW_AVAILCPU; // alternatively, try HW_NCPU;
sysctl(mib, 2, &nCPUs, &len, NULL, 0);
if (nCPUs < 1)
{
// 2) Try alternatively HW_NCPU.
mib[1] = HW_NCPU;
sysctl(mib, 2, &nCPUs, &len, NULL, 0);
}
// Linux, Solaris, AIX
#elif defined(linux) || defined(__linux__)
nCPUs = sysconf(_SC_NPROCESSORS_ONLN);
#else
#warning "Unsupported OS"
#endif // WIN32
if (nCPUs < 1)
{
GfOut("Could not get the number of CPUs here ; assuming only 1\n");
nCPUs = 1;
}
else
GfOut("Detected %d CPUs\n", nCPUs);
return nCPUs;
}

View file

@ -51,6 +51,7 @@ EXPORTS
GfParmGetFileName
GfTime2Str
GfTimeClock
GfGetNumberOfCPUs
gfMean
gfMeanReset
GfPoolMalloc

View file

@ -407,6 +407,9 @@ typedef struct
extern tdble gfMean(tdble v, tMeanVal *pvt, int n, int w);
extern void gfMeanReset(tdble v, tMeanVal *pvt);
/* Get the actual number of CPUs / cores */
extern int GfGetNumberOfCPUs();
/* Run-time dirs accessors */
extern const char *GetLocalDir(void);
extern const char *SetLocalDir(const char *buf);