mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-03-30 10:06:42 +00:00
Issue #19: factored out local script handling into a separate class
This also fixes a bug related to self-destructing references (introduced during the cell handling improvements)
This commit is contained in:
parent
5bfd953dd4
commit
10778d8c3e
8 changed files with 152 additions and 49 deletions
|
@ -149,6 +149,7 @@ set(GAMEWORLD
|
||||||
mwworld/containerutil.cpp
|
mwworld/containerutil.cpp
|
||||||
mwworld/player.cpp
|
mwworld/player.cpp
|
||||||
mwworld/cells.cpp
|
mwworld/cells.cpp
|
||||||
|
mwworld/localscripts.cpp
|
||||||
)
|
)
|
||||||
set(GAMEWORLD_HEADER
|
set(GAMEWORLD_HEADER
|
||||||
mwworld/refdata.hpp
|
mwworld/refdata.hpp
|
||||||
|
@ -170,6 +171,7 @@ set(GAMEWORLD_HEADER
|
||||||
mwworld/player.hpp
|
mwworld/player.hpp
|
||||||
mwworld/cellfunctors.hpp
|
mwworld/cellfunctors.hpp
|
||||||
mwworld/cells.hpp
|
mwworld/cells.hpp
|
||||||
|
mwworld/localscripts.hpp
|
||||||
)
|
)
|
||||||
source_group(apps\\openmw\\mwworld FILES ${GAMEWORLD} ${GAMEWORLD_HEADER})
|
source_group(apps\\openmw\\mwworld FILES ${GAMEWORLD} ${GAMEWORLD_HEADER})
|
||||||
|
|
||||||
|
|
|
@ -54,22 +54,23 @@
|
||||||
|
|
||||||
void OMW::Engine::executeLocalScripts()
|
void OMW::Engine::executeLocalScripts()
|
||||||
{
|
{
|
||||||
for (MWWorld::World::ScriptList::const_iterator iter (
|
MWWorld::LocalScripts& localScripts = mEnvironment.mWorld->getLocalScripts();
|
||||||
mEnvironment.mWorld->getLocalScripts().begin());
|
|
||||||
iter!=mEnvironment.mWorld->getLocalScripts().end(); ++iter)
|
|
||||||
{
|
|
||||||
if (mIgnoreLocalPtr.isEmpty() || mIgnoreLocalPtr!=iter->second)
|
|
||||||
{
|
|
||||||
MWScript::InterpreterContext interpreterContext (mEnvironment,
|
|
||||||
&iter->second.getRefData().getLocals(), MWWorld::Ptr (iter->second));
|
|
||||||
mScriptManager->run (iter->first, interpreterContext);
|
|
||||||
|
|
||||||
if (mEnvironment.mWorld->hasCellChanged())
|
localScripts.startIteration();
|
||||||
break;
|
|
||||||
}
|
while (!localScripts.isFinished())
|
||||||
|
{
|
||||||
|
std::pair<std::string, MWWorld::Ptr> script = localScripts.getNext();
|
||||||
|
|
||||||
|
MWScript::InterpreterContext interpreterContext (mEnvironment,
|
||||||
|
&script.second.getRefData().getLocals(), script.second);
|
||||||
|
mScriptManager->run (script.first, interpreterContext);
|
||||||
|
|
||||||
|
if (mEnvironment.mWorld->hasCellChanged())
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mIgnoreLocalPtr = MWWorld::Ptr();
|
mEnvironment.mWorld->getLocalScripts().setIgnore (MWWorld::Ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -488,7 +489,7 @@ void OMW::Engine::activate()
|
||||||
|
|
||||||
if (!script.empty())
|
if (!script.empty())
|
||||||
{
|
{
|
||||||
mIgnoreLocalPtr = ptr;
|
mEnvironment.mWorld->getLocalScripts().setIgnore (ptr);
|
||||||
mScriptManager->run (script, interpreterContext);
|
mScriptManager->run (script, interpreterContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,8 +81,6 @@ namespace OMW
|
||||||
int focusFrameCounter;
|
int focusFrameCounter;
|
||||||
static const int focusUpdateFrame = 10;
|
static const int focusUpdateFrame = 10;
|
||||||
|
|
||||||
MWWorld::Ptr mIgnoreLocalPtr;
|
|
||||||
|
|
||||||
Files::Collections mFileCollections;
|
Files::Collections mFileCollections;
|
||||||
bool mFSStrict;
|
bool mFSStrict;
|
||||||
|
|
||||||
|
|
80
apps/openmw/mwworld/localscripts.cpp
Normal file
80
apps/openmw/mwworld/localscripts.cpp
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
|
||||||
|
#include "localscripts.hpp"
|
||||||
|
|
||||||
|
void MWWorld::LocalScripts::setIgnore (const Ptr& ptr)
|
||||||
|
{
|
||||||
|
mIgnore = ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MWWorld::LocalScripts::startIteration()
|
||||||
|
{
|
||||||
|
mIter = mScripts.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MWWorld::LocalScripts::isFinished() const
|
||||||
|
{
|
||||||
|
if (mIter==mScripts.end())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!mIgnore.isEmpty() && mIter->second==mIgnore)
|
||||||
|
{
|
||||||
|
std::list<std::pair<std::string, Ptr> >::iterator iter = mIter;
|
||||||
|
return ++iter==mScripts.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<std::string, MWWorld::Ptr> MWWorld::LocalScripts::getNext()
|
||||||
|
{
|
||||||
|
assert (!isFinished());
|
||||||
|
|
||||||
|
std::list<std::pair<std::string, Ptr> >::iterator iter = mIter++;
|
||||||
|
|
||||||
|
if (mIgnore.isEmpty() || iter->second!=mIgnore)
|
||||||
|
return *iter;
|
||||||
|
|
||||||
|
return getNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MWWorld::LocalScripts::add (const std::string& scriptName, const Ptr& ptr)
|
||||||
|
{
|
||||||
|
mScripts.push_back (std::make_pair (scriptName, ptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MWWorld::LocalScripts::clear()
|
||||||
|
{
|
||||||
|
mScripts.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MWWorld::LocalScripts::clearCell (Ptr::CellStore *cell)
|
||||||
|
{
|
||||||
|
std::list<std::pair<std::string, Ptr> >::iterator iter = mScripts.begin();
|
||||||
|
|
||||||
|
while (iter!=mScripts.end())
|
||||||
|
{
|
||||||
|
if (iter->second.getCell()==cell)
|
||||||
|
{
|
||||||
|
if (iter==mIter)
|
||||||
|
++mIter;
|
||||||
|
|
||||||
|
mScripts.erase (iter++);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MWWorld::LocalScripts::remove (const Ptr& ptr)
|
||||||
|
{
|
||||||
|
for (std::list<std::pair<std::string, Ptr> >::iterator iter = mScripts.begin();
|
||||||
|
iter!=mScripts.end(); ++iter)
|
||||||
|
if (iter->second==ptr)
|
||||||
|
{
|
||||||
|
if (iter==mIter)
|
||||||
|
++mIter;
|
||||||
|
|
||||||
|
mScripts.erase (iter);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
47
apps/openmw/mwworld/localscripts.hpp
Normal file
47
apps/openmw/mwworld/localscripts.hpp
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
#ifndef GAME_MWWORLD_LOCALSCRIPTS_H
|
||||||
|
#define GAME_MWWORLD_LOCALSCRIPTS_H
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "ptr.hpp"
|
||||||
|
|
||||||
|
namespace MWWorld
|
||||||
|
{
|
||||||
|
/// \brief List of active local scripts
|
||||||
|
class LocalScripts
|
||||||
|
{
|
||||||
|
std::list<std::pair<std::string, Ptr> > mScripts;
|
||||||
|
std::list<std::pair<std::string, Ptr> >::iterator mIter;
|
||||||
|
MWWorld::Ptr mIgnore;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void setIgnore (const Ptr& ptr);
|
||||||
|
///< Mark a single reference for ignoring during iteration over local scripts (will revoke
|
||||||
|
/// previous ignores).
|
||||||
|
|
||||||
|
void startIteration();
|
||||||
|
///< Set the iterator to the begin of the script list.
|
||||||
|
|
||||||
|
bool isFinished() const;
|
||||||
|
///< Is iteration finished?
|
||||||
|
|
||||||
|
std::pair<std::string, Ptr> getNext();
|
||||||
|
///< Get next local script (must not be called if isFinished())
|
||||||
|
|
||||||
|
void add (const std::string& scriptName, const Ptr& ptr);
|
||||||
|
///< Add script to collection of active local scripts.
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
///< Clear active local scripts collection.
|
||||||
|
|
||||||
|
void clearCell (Ptr::CellStore *cell);
|
||||||
|
///< Remove all scripts belonging to \a cell.
|
||||||
|
|
||||||
|
void remove (const Ptr& ptr);
|
||||||
|
///< Remove script for given reference (ignored if reference does not have a scirpt listed).
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -57,7 +57,7 @@ namespace MWWorld
|
||||||
mPhysics->removeObject (*iter);
|
mPhysics->removeObject (*iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
mWorld->removeScripts (iter->first);
|
mWorld->getLocalScripts().clearCell (iter->first);
|
||||||
|
|
||||||
mEnvironment.mMechanicsManager->dropActors (iter->first);
|
mEnvironment.mMechanicsManager->dropActors (iter->first);
|
||||||
mEnvironment.mSoundManager->stopSound (iter->first);
|
mEnvironment.mSoundManager->stopSound (iter->first);
|
||||||
|
|
|
@ -27,7 +27,7 @@ namespace
|
||||||
{
|
{
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void listCellScripts (const ESMS::ESMStore& store,
|
void listCellScripts (const ESMS::ESMStore& store,
|
||||||
ESMS::CellRefList<T, MWWorld::RefData>& cellRefList, MWWorld::World::ScriptList& scriptList,
|
ESMS::CellRefList<T, MWWorld::RefData>& cellRefList, MWWorld::LocalScripts& localScripts,
|
||||||
MWWorld::Ptr::CellStore *cell)
|
MWWorld::Ptr::CellStore *cell)
|
||||||
{
|
{
|
||||||
for (typename ESMS::CellRefList<T, MWWorld::RefData>::List::iterator iter (
|
for (typename ESMS::CellRefList<T, MWWorld::RefData>::List::iterator iter (
|
||||||
|
@ -40,8 +40,7 @@ namespace
|
||||||
{
|
{
|
||||||
iter->mData.setLocals (*script);
|
iter->mData.setLocals (*script);
|
||||||
|
|
||||||
scriptList.push_back (
|
localScripts.add (iter->base->script, MWWorld::Ptr (&*iter, cell));
|
||||||
std::make_pair (iter->base->script, MWWorld::Ptr (&*iter, cell)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -185,20 +184,6 @@ namespace MWWorld
|
||||||
throw std::runtime_error ("month out of range");
|
throw std::runtime_error ("month out of range");
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::removeScripts (Ptr::CellStore *cell)
|
|
||||||
{
|
|
||||||
ScriptList::iterator iter = mLocalScripts.begin();
|
|
||||||
|
|
||||||
while (iter!=mLocalScripts.end())
|
|
||||||
{
|
|
||||||
if (iter->second.getCell()==cell)
|
|
||||||
mLocalScripts.erase (iter++);
|
|
||||||
else
|
|
||||||
++iter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void World::adjustSky()
|
void World::adjustSky()
|
||||||
{
|
{
|
||||||
if (mSky)
|
if (mSky)
|
||||||
|
@ -306,7 +291,7 @@ namespace MWWorld
|
||||||
return mEsm;
|
return mEsm;
|
||||||
}
|
}
|
||||||
|
|
||||||
const World::ScriptList& World::getLocalScripts() const
|
LocalScripts& World::getLocalScripts()
|
||||||
{
|
{
|
||||||
return mLocalScripts;
|
return mLocalScripts;
|
||||||
}
|
}
|
||||||
|
@ -575,13 +560,7 @@ namespace MWWorld
|
||||||
|
|
||||||
mPhysics->removeObject (ptr.getRefData().getHandle());
|
mPhysics->removeObject (ptr.getRefData().getHandle());
|
||||||
|
|
||||||
for (ScriptList::iterator iter = mLocalScripts.begin(); iter!=mLocalScripts.end();
|
mLocalScripts.remove (ptr);
|
||||||
++iter)
|
|
||||||
if (ptr==iter->second)
|
|
||||||
{
|
|
||||||
mLocalScripts.erase (iter);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render->deleteObject (ptr.getRefData().getHandle());
|
render->deleteObject (ptr.getRefData().getHandle());
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "scene.hpp"
|
#include "scene.hpp"
|
||||||
#include "physicssystem.hpp"
|
#include "physicssystem.hpp"
|
||||||
#include "cells.hpp"
|
#include "cells.hpp"
|
||||||
|
#include "localscripts.hpp"
|
||||||
|
|
||||||
#include <openengine/bullet/physic.hpp>
|
#include <openengine/bullet/physic.hpp>
|
||||||
|
|
||||||
|
@ -55,9 +56,7 @@ namespace MWWorld
|
||||||
|
|
||||||
class World
|
class World
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef std::list<std::pair<std::string, Ptr> > ScriptList;
|
|
||||||
|
|
||||||
enum RenderMode
|
enum RenderMode
|
||||||
{
|
{
|
||||||
|
@ -71,7 +70,7 @@ namespace MWWorld
|
||||||
MWWorld::Player *mPlayer;
|
MWWorld::Player *mPlayer;
|
||||||
ESM::ESMReader mEsm;
|
ESM::ESMReader mEsm;
|
||||||
ESMS::ESMStore mStore;
|
ESMS::ESMStore mStore;
|
||||||
ScriptList mLocalScripts;
|
LocalScripts mLocalScripts;
|
||||||
MWWorld::Globals *mGlobalVariables;
|
MWWorld::Globals *mGlobalVariables;
|
||||||
MWWorld::PhysicsSystem *mPhysics;
|
MWWorld::PhysicsSystem *mPhysics;
|
||||||
bool mSky;
|
bool mSky;
|
||||||
|
@ -108,8 +107,6 @@ namespace MWWorld
|
||||||
|
|
||||||
Ptr::CellStore *getInterior (const std::string& name);
|
Ptr::CellStore *getInterior (const std::string& name);
|
||||||
|
|
||||||
void removeScripts (Ptr::CellStore *cell);
|
|
||||||
|
|
||||||
void insertInteriorScripts (ESMS::CellStore<RefData>& cell);
|
void insertInteriorScripts (ESMS::CellStore<RefData>& cell);
|
||||||
|
|
||||||
void adjustSky();
|
void adjustSky();
|
||||||
|
@ -120,8 +117,7 @@ namespace MWWorld
|
||||||
|
|
||||||
ESM::ESMReader& getEsmReader();
|
ESM::ESMReader& getEsmReader();
|
||||||
|
|
||||||
const ScriptList& getLocalScripts() const;
|
LocalScripts& getLocalScripts();
|
||||||
///< Names and local variable state of all local scripts in active cells.
|
|
||||||
|
|
||||||
bool hasCellChanged() const;
|
bool hasCellChanged() const;
|
||||||
///< Has the player moved to a different cell, since the last frame?
|
///< Has the player moved to a different cell, since the last frame?
|
||||||
|
|
Loading…
Reference in a new issue