Revision: 2535 http://rigsofrods.svn.sourceforge.net/rigsofrods/?rev=2535&view=rev Author: ulteq Date: 2012-05-10 07:15:10 +0000 (Thu, 10 May 2012) Log Message: ----------- -fixed threading
Modified Paths: -------------- trunk/source/main/gameplay/Savegame.cpp trunk/source/main/physics/Beam.cpp trunk/source/main/physics/Beam.h trunk/source/main/physics/BeamFactory.cpp trunk/source/main/physics/BeamFactory.h Modified: trunk/source/main/gameplay/Savegame.cpp =================================================================== --- trunk/source/main/gameplay/Savegame.cpp 2012-05-09 04:38:47 UTC (rev 2534) +++ trunk/source/main/gameplay/Savegame.cpp 2012-05-10 07:15:10 UTC (rev 2535) @@ -45,8 +45,7 @@ LOG("trying to save savegame as " + filename + " ..."); FILE *f = fopen(filename.c_str(), "wb"); - // wait for engine sync - //BEAMLOCK(); + // wait for engine sync? // TODO: show error if(!f) Modified: trunk/source/main/physics/Beam.cpp =================================================================== --- trunk/source/main/physics/Beam.cpp 2012-05-09 04:38:47 UTC (rev 2534) +++ trunk/source/main/physics/Beam.cpp 2012-05-10 07:15:10 UTC (rev 2535) @@ -68,11 +68,411 @@ # include "crashrpt.h" #endif -// Birthtime +// time of birth float mrtime; using namespace Ogre; + +void *threadstart(void* vid); +Beam* Beam::threadbeam[MAX_TRUCKS]; +int Beam::thread_mode = THREAD_SINGLE; +int Beam::free_tb = 0; + +Beam::Beam(int tnum, SceneManager *manager, SceneNode *parent, RenderWindow* win, Network *_net, float *_mapsizex, float *_mapsizez, Real px, Real py, Real pz, Quaternion rot, const char* fname, Collisions *icollisions, HeightFinder *mfinder, Water *w, Camera *pcam, bool networked, bool networking, collision_box_t *spawnbox, bool ismachine, int _flaresMode, std::vector<String> *_truckconfig, Skin *skin, bool freeposition) : + deleting(false) + , abs_state(false) + , abs_timer(0.0) + , aileron(0) + , avichatter_timer(11.0f) // some pseudo random number, doesn't matter + , beacon(false) + , blinkingtype(BLINK_NONE) + , blinktreshpassed(false) + , brake(0.0) + , cabFadeMode(0) + , cabFadeTime(0.3) + , cabFadeTimer(0) + , cameranodeacc(Vector3::ZERO) + , cameranodecount(0) + , canwork(1) + , collisions(icollisions) + , cparticle_mode(false) + , currentScale(1) + , currentcamera(-1) // -1 = external + , dash(nullptr) + , detailLevel(0) + , disableDrag(false) + , elevator(0) + , fasted(1) + , flap(0) + , floating_origin_enable(true) + , fusedrag(Vector3::ZERO) + , hydroaileroncommand(0) + , hydroaileronstate(0) + , hydrodircommand(0) + , hydrodirstate(0) + , hydrodirwheeldisplay(0.0) + , hydroelevatorcommand(0) + , hydroelevatorstate(0) + , hydroruddercommand(0) + , hydrorudderstate(0) + , ipy(py) + , isInside(false) + , label(tnum) // convenient, but set overwise elsewhere for a good cause + , lastFuzzyGroundModel(0) + , last_net_time(0) + , lastlastposition(Vector3(px, py, pz)) + , lastposition(Vector3(px, py, pz)) + , lastwspeed(0.0) + , leftMirrorAngle(0.52) + , lights(1) + , lockSkeletonchange(false) + , mTimeUntilNextToggle(0) + , mWindow(win) + , mapsizex(_mapsizex) + , mapsizez(_mapsizez) + , meshesVisible(true) + , minCameraRadius(0) + , mousemoveforce(0.0f) + , mousenode(-1) + , mousepos(Vector3::ZERO) + , net(_net) + , netBrakeLight(false) + , netLabelNode(0) + , netMT(0) + , netReverseLight(false) + , networkAuthlevel(0) + , networkUsername("") + , oldreplaypos(-1) + , parentNode(parent) + , parkingbrake(0) + , posStorage(0) + , position(Vector3(px, py, pz)) + , previousGear(0) + , refpressure(50.0) + , replay(0) + , replayPrecision(0) + , replayTimer(0) + , replaylen(10000) + , replaymode(false) + , replaypos(0) + , requires_wheel_contact(false) + , reset_requested(0) + , reverselight(false) + , rightMirrorAngle(-0.52) + , rudder(0) + , simpleSkeletonInitiated(false) + , simpleSkeletonManualObject(0) + , skeleton(0) + , sleepcount(0) + , slowed(1) + , smokeNode(NULL) + , smoker(NULL) + , stabcommand(0) + , stabratio(0.0) + , stabsleep(0.0) + , tdt(0.1) + , totalmass(0) + , tsm(manager) + , tsteps(100) + , ttdt(0.1) + , watercontact(0) + , watercontactold(0) +{ + + airbrakeval = 0; + alb_minspeed = 0.0f; + alb_mode = 0; + alb_notoggle = false; + alb_notoggle = false; + alb_present = false; + alb_pulse = 1; + alb_pulse_state = false; + alb_ratio = 0.0f; + animTimer = 0.0f; + antilockbrake = 0; + + cabMesh = NULL; + cablight = 0; + cablightNode = 0; + + cc_mode = 0; + cc_target_rpm = 0; + cc_target_speed = 0; + + debugVisuals = 0; + + driveable = NOT_DRIVEABLE; + driverSeat = 0; + + enable_wheel2 = true; // since 0.38 enabled wheels2 by default + engine = 0; + + flaresMode = _flaresMode; + + freePositioned = freeposition; + free_aeroengine = 0; + free_airbrake = 0; + free_axle = 0; + free_beam = 0; + free_buoycab = 0; + free_cab = 0; + free_camerarail = 0; + free_collcab = 0; + free_contacter = 0; + free_cparticle = 0; + free_flare = 0; + free_flexbody = 0; + free_hydro = 0; + free_node = 0; + free_pressure_beam = 0; + free_prop = 0; + free_rigidifier = 0; + free_rotator = 0; + free_screwprop = 0; + free_shock = 0; + free_soundsource = 0; + free_sub = 0; + free_texcoord = 0; + free_wheel = 0; + free_wing = 0; + + heathaze = !disable_smoke && BSETTING("HeatHaze", false); + hfinder = mfinder; + hideInChooser = false; + + mCamera = pcam; + + mrtime = 0.0; + + networking = networking; + + origin = Vector3::ZERO; + + previousCrank = 0.0f; + + state = SLEEPING; + tc_fade = 0.0f; + tc_mode = 0; + tc_present = false; + tc_pulse = 1; + tc_pulse_state = false; + tc_ratio = 0.0f; + tc_wheelslip = 0.0f; + tcalb_timer = 0.0f; + + tractioncontrol = 0; + trucknum = tnum; + + usedSkin = skin; + water = w; + +#ifdef USE_MYGUI + dash = new DashBoardManager(); +#endif // USE_MYGUI + +#ifdef FEAT_TIMING + // this enables beam engine timing statistics + statistics = BES.getClient(tnum, BES_CORE); + statistics_gfx = BES.getClient(tnum, BES_GFX); +#endif + + if (net) networking = true; // enable networking if some network class is existing + + for(int i=0; i<MAX_SUBMESHES; i++) + { + subisback[i] = 0; + } + + LOG("BEAM: loading new truck: " + String(fname)); + + if (ismachine) + { + driveable = MACHINE; + } + + // copy truck config + if (_truckconfig && _truckconfig->size()) + { + for(std::vector<String>::iterator it = _truckconfig->begin(); it != _truckconfig->end(); it++) + { + truckconfig.push_back(*it); + } + } + + materialFunctionMapper = new MaterialFunctionMapper(); + cmdInertia = new CmdKeyInertia(MAX_COMMANDS); + hydroInertia = new CmdKeyInertia(MAX_HYDROS); + rotaInertia = new CmdKeyInertia(MAX_COMMANDS); // NOT MAX_ROTATORS + + submesh_ground_model = icollisions->defaultgm; + + realtruckfilename = String(fname); + sprintf(truckname, "t%i", tnum); + + strcpy(uniquetruckid,"-1"); + + simpleSkeletonNode = parent->createChildSceneNode(); + deletion_sceneNodes.push_back(simpleSkeletonNode); + + beamsRoot=parent->createChildSceneNode(); + deletion_sceneNodes.push_back(netLabelNode); + + if (networked) + { + state = NETWORKED; //required for proper loading + } + + // initialize commands + for (int i=0; i<MAX_COMMANDS; i++) + { + commandkey[i].commandValueState = -1; + commandkey[i].commandValue = 0; + } + + // skidmark stuff + useSkidmarks = BSETTING("Skidmarks", false); + + // always init skidmarks with 0 + for(int i=0; i<MAX_WHEELS*2; i++) + { + skidtrails[i] = 0; + } + + // you could disable the collision code here: + // pointCD = 0; + pointCD = new PointColDetector(); + + dustp = DustManager::getSingleton().getDustPool("dust"); + dripp = DustManager::getSingleton().getDustPool("dripp"); + sparksp = DustManager::getSingleton().getDustPool("sparks"); + clumpp = DustManager::getSingleton().getDustPool("clump"); + splashp = DustManager::getSingleton().getDustPool("splash"); + ripplep = DustManager::getSingleton().getDustPool("ripple"); + + if (networked || networking) + { + enable_wheel2 = false; + } + + cparticle_enabled = BSETTING("Particles", true); + if (strnlen(fname, 200) > 0) + { + if (loadTruck2(String(fname), manager, parent, Vector3(px, py, pz), rot, spawnbox)) + { + return; + } + } + + // setup sounds properly + changedCamera(); + + // setup replay mode + bool enablereplay = BSETTING("Replay mode", false); + + if (enablereplay && state != NETWORKED && !networking) + { + replaylen = ISETTING("Replay length", 10000); + replay = new Replay(this, replaylen); + + int steps = ISETTING("Replay Steps per second", 240); + + if (steps <= 0) + replayPrecision = 0.0f; + else + replayPrecision = 1.0f / ((float)steps); + } + + // add storage + bool enablePosStor = BSETTING("Position Storage", false); + if (enablePosStor) + { + posStorage = new PositionStorage(free_node, 10); + } + + //search first_wheel_node + first_wheel_node=free_node; + for (int i=0; i<free_node; i++) + { + if (nodes[i].iswheel) + { + first_wheel_node=i; + break; + } + } + + // network buffer layout (without oob_t): + // + // - 3 floats (x,y,z) for the reference node 0 + // - free_node - 1 times 3 short ints (compressed position info) + // - free_wheel times a float for the wheel rotation + // + nodebuffersize = sizeof(float) * 3 + (first_wheel_node-1) * sizeof(short int) * 3; + netbuffersize = nodebuffersize + free_wheel * sizeof(float); + updateVisual(); + // stop lights + lightsToggle(); + + updateFlares(0); + updateProps(); + if (engine) + { + engine->offstart(); + } + // pressurize tires + addPressure(0.0); + + checkBeamMaterial(); + + // start thread stuff + if (thread_mode == THREAD_MULTI) + { + // init mutexes + pthread_mutex_init(&work_mutex, NULL); + pthread_cond_init(&work_cv, NULL); + + pthread_mutex_init(&done_count_mutex, NULL); + pthread_cond_init(&done_count_cv, NULL); + + threadbeam[free_tb] = this; + done_count = 1; + free_tb++; + + if (pthread_create(&thread, NULL, threadstart, (void*)(free_tb-1))) + { + LOG("BEAM: Can not start a thread"); + } + _waitForSync(); + } + + // start network stuff + if (networked) + { + state=NETWORKED; + // malloc memory + oob1=(oob_t*)malloc(sizeof(oob_t)); + oob2=(oob_t*)malloc(sizeof(oob_t)); + oob3=(oob_t*)malloc(sizeof(oob_t)); + netb1=(char*)malloc(netbuffersize); + netb2=(char*)malloc(netbuffersize); + netb3=(char*)malloc(netbuffersize); + nettimer = new Timer(); + net_toffset=0; + netcounter=0; + // init mutex + pthread_mutex_init(&net_mutex, NULL); + if (engine) + { + engine->start(); + } + } + + if (networking) + { + sendStreamSetup(); + } +} + Beam::~Beam() { // TODO: IMPROVE below: delete/destroy prop entities, etc @@ -82,6 +482,8 @@ // hide all meshes, prevents deleting stuff while drawing this->setMeshVisibility(false); + _waitForSync(); + // delete all classes we might have constructed #ifdef USE_MYGUI if(dash) delete dash; dash=0; @@ -283,346 +685,6 @@ } } -Beam::Beam(int tnum, SceneManager *manager, SceneNode *parent, RenderWindow* win, Network *_net, float *_mapsizex, float *_mapsizez, Real px, Real py, Real pz, Quaternion rot, const char* fname, Collisions *icollisions, HeightFinder *mfinder, Water *w, Camera *pcam, bool networked, bool networking, collision_box_t *spawnbox, bool ismachine, int _flaresMode, std::vector<String> *_truckconfig, Skin *skin, bool freeposition) : \ - deleting(false), dash(nullptr) -{ -#ifdef USE_MYGUI - dash = new DashBoardManager(); -#endif // USE_MYGUI - net=_net; - if(net && !networking) networking = true; // enable networking if some network class is existing - - avichatter_timer=11.0f; // some pseudo random number, doesnt matter ;) - tsteps=100; - driverSeat=0; - submesh_ground_model = icollisions->defaultgm; - networkUsername = String(); - networkAuthlevel = 0; - freePositioned = freeposition; - free_axle=0; - replayTimer=0; - minCameraRadius=0; - last_net_time=0; - lastFuzzyGroundModel=0; - usedSkin = skin; - LOG("BEAM: loading new truck: " + String(fname)); - trucknum=tnum; - currentScale=1; - // copy truck config - if(_truckconfig && _truckconfig->size()) - for(std::vector<String>::iterator it = _truckconfig->begin(); it!=_truckconfig->end();it++) - truckconfig.push_back(*it); - materialFunctionMapper = new MaterialFunctionMapper(); - cmdInertia = new CmdKeyInertia(MAX_COMMANDS); - hydroInertia = new CmdKeyInertia(MAX_HYDROS); - rotaInertia = new CmdKeyInertia(MAX_COMMANDS); // NOT MAX_ROTATORS - free_soundsource=0; - debugVisuals=0; - netMT = 0; - meshesVisible=true; - -#ifdef FEAT_TIMING - // this enables beam engine timing statistics - statistics = BES.getClient(tnum, BES_CORE); - statistics_gfx = BES.getClient(tnum, BES_GFX); -#endif - - //truckScript = new TruckCommandScheduler(); - flaresMode = _flaresMode; - airbrakeval=0; - origin=Vector3::ZERO; - cameranodeacc=Vector3::ZERO; - cameranodecount=0; - label=tnum; //convenient, but set overwise elsewhere for a good cause - this->networking=networking; - mapsizex = _mapsizex; - mapsizez = _mapsizez; - floating_origin_enable=true; - lockSkeletonchange=false; - reset_requested=0; - mrtime=0.0; - free_flexbody=0; - netLabelNode=0; - free_rigidifier=0; - free_rotator=0; - free_cparticle=0; - free_airbrake=0; - cparticle_mode=false; - mousenode=-1; - mousemoveforce=0.0f; - mousepos=Vector3::ZERO; - cablight=0; - cablightNode=0; - disableDrag=false; - fusedrag=Vector3::ZERO; - elevator=0; - rudder=0; - aileron=0; - flap=0; - free_aeroengine=0; - free_screwprop=0; - free_wing=0; - refpressure=50.0; - free_pressure_beam=0; - leftMirrorAngle=0.52; - rightMirrorAngle=-0.52; - if(ismachine) - driveable=MACHINE; - else - driveable=NOT_DRIVEABLE; - previousGear = 0; - cc_mode = cc_target_rpm = cc_target_speed = 0; - alb_ratio = alb_minspeed = 0.0f; - alb_mode = 0; - tc_ratio = tc_fade = tc_wheelslip = 0.0f; - tc_mode = 0; - tc_pulse = 1; - alb_pulse = 1; - tc_present = alb_present = alb_notoggle = false; - tc_pulse_state = alb_pulse_state = alb_notoggle = false; - tcalb_timer = 0.0f; - previousCrank = 0.0f; - animTimer = 0.0f; - engine=0; - isInside=false; - beacon=false; - realtruckfilename = String(fname); - sprintf(truckname, "t%i", tnum); - simpleSkeletonManualObject=0; - simpleSkeletonInitiated=false; - strcpy(uniquetruckid,"-1"); - tsm=manager; - simpleSkeletonNode = parent->createChildSceneNode(); - deletion_sceneNodes.push_back(simpleSkeletonNode); - - tdt=0.1; - ttdt=0.1; - //load terrain altitudes - // hfinder=new HeightFinder(terrainmap, tsm); - mCamera=pcam; - hfinder=mfinder; - mWindow=win; - beamsRoot=parent->createChildSceneNode(); - deletion_sceneNodes.push_back(netLabelNode); - - parentNode=parent; - // float gears[]={6.0, 3.0, 1.5, 1.0, 0.75}; - // engine=new BeamEngine(1000.0,2000.0, 1870.0, 4.0, 5, gears, 3.42, audio); - //engine=new BeamEngine(1000.0,2000.0, 4000.0, 4.0, 5, gears, 3.42, audio); - - //init - water=w; - detailLevel=0; - // state=DESACTIVATED; - // sleepcount=9; - state=SLEEPING; - if (networked) state=NETWORKED; //required for proper loading - sleepcount=0; - currentcamera=-1; // -1 = external - - requires_wheel_contact=false; - subisback[0]=0; - canwork=1; - totalmass=0; - parkingbrake=0; - antilockbrake = 0; - tractioncontrol = 0; - lights=1; - reverselight=false; - free_node=0; - free_beam=0; - free_contacter=0; - free_hydro=0; - free_wheel=0; - free_sub=0; - free_texcoord=0; - free_cab=0; - free_collcab=0; - free_buoycab=0; - free_shock=0; - free_flare=0; - free_prop=0; - free_camerarail=0; - lastwspeed=0.0; - stabcommand=0; - stabratio=0.0; - stabsleep=0.0; - cabMesh=NULL; - smokeNode=NULL; - smoker=NULL; - brake=0.0; - hideInChooser=false; - abs_timer=0.0; - abs_state=false; - blinktreshpassed=false; - blinkingtype=BLINK_NONE; - mTimeUntilNextToggle = 0; - netBrakeLight = false; - netReverseLight = false; - skeleton=0; - fasted=1; - slowed=1; - hydrodircommand=0; - hydrodirstate=0; - hydrodirwheeldisplay=0.0; - hydroaileroncommand=0; - hydroaileronstate=0; - hydroruddercommand=0; - hydrorudderstate=0; - hydroelevatorcommand=0; - hydroelevatorstate=0; - replaymode=false; - replaypos=0; - replayPrecision=0; - oldreplaypos=-1; - watercontact=0; - watercontactold=0; - // initialize commands - for (int i=0; i<MAX_COMMANDS; i++) - { - commandkey[i].commandValueState = -1; - commandkey[i].commandValue = 0; - } - ipy=py; - position=Vector3(px,py,pz); - lastposition=Vector3(px,py,pz); - lastlastposition=Vector3(px,py,pz); - - cabFadeMode = 0; - cabFadeTimer=0; - cabFadeTime=0.3; - - // skidmark stuff - useSkidmarks = BSETTING("Skidmarks", false); - - // always init skidmarks with 0 - for(int i=0; i<MAX_WHEELS*2; i++) skidtrails[i] = 0; - - collisions=icollisions; - - // you could disable the collision code here: - // pointCD = 0; - pointCD = new PointColDetector(); - - - dustp = DustManager::getSingleton().getDustPool("dust"); - dripp = DustManager::getSingleton().getDustPool("dripp"); - sparksp = DustManager::getSingleton().getDustPool("sparks"); - clumpp = DustManager::getSingleton().getDustPool("clump"); - splashp = DustManager::getSingleton().getDustPool("splash"); - ripplep = DustManager::getSingleton().getDustPool("ripple"); - - heathaze=BSETTING("HeatHaze", false); - if(heathaze && disable_smoke) - // no heathaze without smoke! - heathaze=false; - - - enable_wheel2=true; // since 0.38, enabled wheels2 by default // BSETTING("Enhanced wheels"); - if (networked || networking) enable_wheel2=false; - - cparticle_enabled=BSETTING("Particles", true); - if(strnlen(fname,200) > 0) - { - if(loadTruck2(String(fname), manager, parent, Vector3(px, py, pz), rot, spawnbox)) - { - return; - } - } - - - - - // printf("%i nodes, %i beams\n", free_node, free_beam); - - // setup sounds properly - changedCamera(); - - // setup replay mode - bool enablereplay = BSETTING("Replay mode", false); - replay=0; - replaylen = 10000; - if(enablereplay && state != NETWORKED && !networking) - { - replaylen = ISETTING("Replay length", 10000); - replay = new Replay(this, replaylen); - - int steps = ISETTING("Replay Steps per second", 240); - - if(steps <= 0) - replayPrecision = 0.0f; - else - replayPrecision = 1.0f / ((float)steps); - } - - // add storage - posStorage=0; - bool enablePosStor = BSETTING("Position Storage", false); - if(enablePosStor) - { - posStorage = new PositionStorage(free_node, 10); - } - - //search first_wheel_node - first_wheel_node=free_node; - for (int i=0; i<free_node; i++) - { - if (nodes[i].iswheel) - { - first_wheel_node=i; - break; - } - } - // network buffer layout (without oob_t): - // - // - 3 floats (x,y,z) for the reference node 0 - // - free_node - 1 times 3 short ints (compressed position info) - // - free_wheel times a float for the wheel rotation - // - nodebuffersize = sizeof(float) * 3 + (first_wheel_node-1) * sizeof(short int) * 3; - netbuffersize = nodebuffersize + free_wheel * sizeof(float); - updateVisual(); - // stop lights - lightsToggle(); - - updateFlares(0); - updateProps(); - if (engine) engine->offstart(); - // pressurize tires - addPressure(0.0); - - checkBeamMaterial(); - - // start network stuff - if (networked) - { - state=NETWORKED; - // malloc memory - oob1=(oob_t*)malloc(sizeof(oob_t)); - oob2=(oob_t*)malloc(sizeof(oob_t)); - oob3=(oob_t*)malloc(sizeof(oob_t)); - netb1=(char*)malloc(netbuffersize); - netb2=(char*)malloc(netbuffersize); - netb3=(char*)malloc(netbuffersize); - nettimer = new Timer(); - net_toffset=0; - netcounter=0; - // init mutex - pthread_mutex_init(&net_mutex, NULL); - if (engine) engine->start(); - } - - if(networking) - { - sendStreamSetup(); - } - - //if(networked) - // showSkeleton(true, true); - - //updateDebugOverlay(); -} - // This method scales trucks. Stresses should *NOT* be scaled, they describe // the material type and they do not depend on length or scale. void Beam::scaleTruck(float value) @@ -1942,7 +2004,7 @@ ); */ if (!loading_finished) return true; - if (state==SLEEPING || state==NETWORKED || state==RECYCLE) return true; + if (state >= SLEEPING) return true; if (dt==0) return true; if(mTimeUntilNextToggle>-1) mTimeUntilNextToggle-= dt; @@ -2049,57 +2111,110 @@ } else { - //simulation update - ttdt=tdt; - tdt=dt; - float dtperstep=dt/(Real)steps; + // simulation update + if (thread_mode == THREAD_SINGLE) + { + ttdt=tdt; + tdt=dt; + float dtperstep=dt/(Real)steps; - for (int i=0; i<steps; i++) - { + for (int i=0; i<steps; i++) + { + for (int t=0; t<numtrucks; t++) + { + if (trucks[t] && trucks[t]->state < SLEEPING) + trucks[t]->calcForcesEuler(i==0, dtperstep, i, steps); + } + truckTruckCollisions(dtperstep); + } + for (int t=0; t<numtrucks; t++) { - if (trucks[t] && trucks[t]->state < SLEEPING) - trucks[t]->calcForcesEuler(i==0, dtperstep, i, steps); + if(!trucks[t]) continue; + + if (trucks[t]->reset_requested) + trucks[t]->SyncReset(); + + if (trucks[t]->state < SLEEPING) + { + trucks[t]->lastlastposition=trucks[t]->lastposition; + trucks[t]->lastposition=trucks[t]->position; + trucks[t]->updateTruckPosition(); + } + if (floating_origin_enable && trucks[t]->nodes[0].RelPosition.length()>100.0) + trucks[t]->moveOrigin(trucks[t]->nodes[0].RelPosition); } - truckTruckCollisions(dtperstep); - } - for (int t=0; t<numtrucks; t++) + ffforce = affforce / steps; + ffhydro = affhydro / steps; + if (free_hydro) ffhydro = ffhydro / free_hydro; + } else { - if(!trucks[t]) continue; + _waitForSync(); - if (trucks[t]->reset_requested) - trucks[t]->SyncReset(); - - if (trucks[t]->state!=SLEEPING && trucks[t]->state!=NETWORKED && trucks[t]->state!=RECYCLE) + for (int t=0; t<numtrucks; t++) { + if(!trucks[t]) continue; trucks[t]->lastlastposition=trucks[t]->lastposition; trucks[t]->lastposition=trucks[t]->position; - trucks[t]->updateTruckPosition(); } - if (floating_origin_enable && trucks[t]->nodes[0].RelPosition.length()>100.0) - trucks[t]->moveOrigin(trucks[t]->nodes[0].RelPosition); + + // smooth + for (int t=0; t<numtrucks; t++) + { + if (!trucks[t]) continue; + if (trucks[t]->reset_requested) trucks[t]->SyncReset(); + if (trucks[t]->state < SLEEPING) + { + trucks[t]->updateTruckPosition(); + } + if (floating_origin_enable && trucks[t]->nodes[0].RelPosition.length()>100.0) + { + trucks[t]->moveOrigin(trucks[t]->nodes[0].RelPosition); + } + } + + tsteps=steps; + ttdt=tdt; + tdt=dt; + ttrucks=trucks; + tnumtrucks=numtrucks; + // preparing workdone + MUTEX_LOCK(&done_count_mutex); + done_count=1; + MUTEX_UNLOCK(&done_count_mutex); + + // unblock threads + MUTEX_LOCK(&work_mutex); + pthread_cond_broadcast(&work_cv); + MUTEX_UNLOCK(&work_mutex); } - ffforce=affforce/steps; - ffhydro=affhydro/steps; - if (free_hydro) ffhydro=ffhydro/free_hydro; - #ifdef FEAT_TIMING if(statistics) statistics->frameStep(dt); if(statistics_gfx) statistics_gfx->frameStep(dt); -#endif - //we must take care of this +#endif // FEAT_TIMING + + // we must take care of this for (int t=0; t<numtrucks; t++) { if(!trucks[t]) continue; - //synchronous sleep - if (trucks[t]->state==GOSLEEP) trucks[t]->state=SLEEPING; + + // synchronous sleep + if (trucks[t]->state==GOSLEEP) trucks[t]->state = SLEEPING; + if (trucks[t]->state==DESACTIVATED) { trucks[t]->sleepcount++; - if ((trucks[t]->lastposition-trucks[t]->lastlastposition).length()/dt>0.1) trucks[t]->sleepcount=7; - if (trucks[t]->sleepcount>10) {trucks[t]->state=MAYSLEEP;trucks[t]->sleepcount=0;} + if ((trucks[t]->lastposition - trucks[t]->lastlastposition).length() / dt>0.1) + { + trucks[t]->sleepcount = 7; + } + if (trucks[t]->sleepcount > 10) + { + trucks[t]->state = MAYSLEEP; + trucks[t]->sleepcount=0; + } } } } @@ -2108,9 +2223,22 @@ void Beam::prepareShutdown() { - //BEAMLOCK(); + _waitForSync(); } +void Beam::_waitForSync() +{ + if (thread_mode == THREAD_MULTI) + { + MUTEX_LOCK(&done_count_mutex); + while (done_count > 0) + { + pthread_cond_wait(&done_count_cv, &done_count_mutex); + } + MUTEX_UNLOCK(&done_count_mutex); + } +} + void Beam::sendStreamSetup() { if(!net || state == NETWORKED ) return; @@ -5182,6 +5310,54 @@ updateVisual(); } +void *threadstart(void* vid) +{ +#ifdef USE_CRASHRPT + if(SSETTING("NoCrashRpt").empty()) + { + // add the crash handler for this thread + CrThreadAutoInstallHelper cr_thread_install_helper; + MYASSERT(cr_thread_install_helper.m_nInstallStatus==0); + } +#endif // USE_CRASHRPT + + // 64 bit systems do have longer addresses! + long int id; + id = (long int)vid; + Beam *beam = Beam::threadbeam[id]; + + try + { + // additional exception handler required, otherwise RoR just crashes upon exception + while (1) + { + // wait signal + MUTEX_LOCK(&beam->work_mutex); + + // signal end + MUTEX_LOCK(&beam->done_count_mutex); + beam->done_count--; + pthread_cond_signal(&beam->done_count_cv); + MUTEX_UNLOCK(&beam->done_count_mutex); + + pthread_cond_wait(&beam->work_cv, &beam->work_mutex); + MUTEX_UNLOCK(&beam->work_mutex); + // do work + beam->threadentry(id); + } + } catch(Ogre::Exception& e) + { + // try to shutdown input system upon an error + if (InputEngine::getSingletonPtrNoCreation()) + INPUTENGINE.prepareShutdown(); + + String url = "http://wiki.rigsofrods.com/index.php?title=Error_" + TOSTRING(e.getNumber())+"#"+e.getSource(); + showOgreWebError("An exception has occured!", e.getFullDescription(), url); + } + pthread_exit(NULL); + return NULL; +} + float Beam::getHeadingDirectionAngle() { int refnode = cameranodepos[0]; Modified: trunk/source/main/physics/Beam.h =================================================================== --- trunk/source/main/physics/Beam.h 2012-05-09 04:38:47 UTC (rev 2534) +++ trunk/source/main/physics/Beam.h 2012-05-10 07:15:10 UTC (rev 2535) @@ -222,6 +222,22 @@ float refpressure; PointColDetector *pointCD; + pthread_mutex_t work_mutex; + pthread_cond_t work_cv; + pthread_mutex_t done_count_mutex; + pthread_cond_t done_count_cv; + pthread_t thread; + int done_count; + + /** + * Blocks until all threads are done. + */ + void _waitForSync(); + + static Beam* threadbeam[MAX_TRUCKS]; + static int thread_mode; + static int free_tb; + int calculateDriverPos(Ogre::Vector3 &pos, Ogre::Quaternion &rot); float getSteeringAngle(); Modified: trunk/source/main/physics/BeamFactory.cpp =================================================================== --- trunk/source/main/physics/BeamFactory.cpp 2012-05-09 04:38:47 UTC (rev 2534) +++ trunk/source/main/physics/BeamFactory.cpp 2012-05-10 07:15:10 UTC (rev 2535) @@ -50,17 +50,15 @@ , w(w) , pcam(pcam) , current_truck(-1) - , done_count(0) , free_truck(0) , physFrame(0) , tdr(0) - , thread_mode(THREAD_SINGLE) { for (int t=0; t < MAX_TRUCKS; t++) trucks[t] = 0; if (SSETTING("Threads", "2 (Hyper-Threading or Dual core CPU)") == "2 (Hyper-Threading or Dual core CPU)") - thread_mode = THREAD_MULTI; + Beam::thread_mode = THREAD_MULTI; if (BSETTING("2DReplay", false)) tdr = new TwoDReplay(); Modified: trunk/source/main/physics/BeamFactory.h =================================================================== --- trunk/source/main/physics/BeamFactory.h 2012-05-09 04:38:47 UTC (rev 2534) +++ trunk/source/main/physics/BeamFactory.h 2012-05-10 07:15:10 UTC (rev 2535) @@ -40,55 +40,54 @@ Beam *createLocal(int slotid); Beam *createLocal(Ogre::Vector3 pos, Ogre::Quaternion rot, Ogre::String fname, collision_box_t *spawnbox=NULL, bool ismachine=false, int flareMode=0, std::vector<Ogre::String> *truckconfig=0, Skin *skin=0, bool freePosition=false); - bool removeBeam(Beam *b); - Beam *createRemoteInstance(stream_reg_t *reg); Beam *getBeam(int source_id, int stream_id); // used by character - int getTruckCount() { return free_truck; }; - Beam *getTruck(int number) { return trucks[number]; }; Beam *getCurrentTruck() { return (current_truck<0)?0:trucks[current_truck]; }; + Beam *getTruck(int number) { return trucks[number]; }; + Beam **getTrucks() { return trucks; }; int getCurrentTruckNumber() { return current_truck; }; - void recalcGravityMasses(); - void repairTruck(Collisions *collisions, char* inst, char* box, bool keepPosition=false); + int getTruckCount() { return free_truck; }; + + void setCurrentTruck(int new_truck); + + bool removeBeam(Beam *b); + void removeCurrentTruck(); void removeTruck(Collisions *collisions, char* inst, char* box); void removeTruck(int truck); - void removeCurrentTruck(); - void setCurrentTruck(int new_truck); + bool enterRescueTruck(); + void repairTruck(Collisions *collisions, char* inst, char* box, bool keepPosition=false); - void activateAllTrucks(); - void sendAllTrucksSleeping(); - void updateVisual(float dt); void updateAI(float dt); inline unsigned long getPhysFrame() { return physFrame; }; void calcPhysics(float dt); + void recalcGravityMasses(); - Beam **getTrucks() { return trucks; }; int updateSimulation(float dt); - // beam engine functions bool checkForActive(int j, bool *sleepyList); + void activateAllTrucks(); void recursiveActivation(int j); + void sendAllTrucksSleeping(); void checkSleepingState(); void windowResized(); protected: - Ogre::SceneManager *manager; - Ogre::SceneNode *parent; - Ogre::RenderWindow* win; - Network *net; - float *mapsizex, *mapsizez; Collisions *icollisions; HeightFinder *mfinder; - Water *w; + Network *net; Ogre::Camera *pcam; - int thread_mode; + Ogre::RenderWindow* win; + Ogre::SceneManager *manager; + Ogre::SceneNode *parent; + Water *w; + float *mapsizex, *mapsizez; Beam *trucks[MAX_TRUCKS]; int free_truck; @@ -98,21 +97,18 @@ unsigned long physFrame; - int done_count; - int getFreeTruckSlot(); + int findTruckInsideBox(Collisions *collisions, char* inst, char* box); // functions used by friends void netUserAttributesChanged(int source, int streamid); void localUserAttributesChanged(int newid); - bool syncRemoteStreams(); void updateGUI(); void removeInstance(Beam *b); void removeInstance(stream_del_t *del); void _deleteTruck(Beam *b); - int findTruckInsideBox(Collisions *collisions, char* inst, char* box); }; #endif // __BeamFactory_H_ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ Live Security Virtual Conference Exclusive live event will cover all the ways today's security and threat landscape has changed and how IT managers can respond. Discussions will include endpoint security, mobile security and the latest in malware threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ _______________________________________________ Rigsofrods-devel mailing list Rigsofrods-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/rigsofrods-devel