mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-22 04:01:23 +00:00
Merge pull request #967 from Akz-/emi-fix-savecrash
EMI: Free materials as soon as they are no longer in use by any costumes
This commit is contained in:
commit
96946a4802
@ -125,11 +125,6 @@ Actor::~Actor() {
|
||||
if (_cleanBuffer) {
|
||||
g_driver->delBuffer(_cleanBuffer);
|
||||
}
|
||||
|
||||
Common::List<Material *>::iterator it = _materials.begin();
|
||||
for (; it != _materials.end(); ++it) {
|
||||
delete (*it);
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::saveState(SaveGame *savedState) const {
|
||||
@ -258,9 +253,12 @@ void Actor::saveState(SaveGame *savedState) const {
|
||||
|
||||
_lastWearChore.saveState(savedState);
|
||||
|
||||
Common::List<Material *>::const_iterator it = _materials.begin();
|
||||
Common::List<MaterialPtr>::const_iterator it = _materials.begin();
|
||||
for (; it != _materials.end(); ++it) {
|
||||
savedState->writeLESint32((*it)->getActiveTexture());
|
||||
if (*it) {
|
||||
warning((*it)->getFilename().c_str());
|
||||
savedState->writeLESint32((*it)->getActiveTexture());
|
||||
}
|
||||
}
|
||||
|
||||
savedState->writeLESint32(_lookAtActor);
|
||||
@ -274,9 +272,6 @@ bool Actor::restoreState(SaveGame *savedState) {
|
||||
delete *i;
|
||||
}
|
||||
_costumeStack.clear();
|
||||
for (Common::List<Material *>::const_iterator i = _materials.begin(); i != _materials.end(); ++i) {
|
||||
delete *i;
|
||||
}
|
||||
_materials.clear();
|
||||
|
||||
// load actor name
|
||||
@ -440,9 +435,11 @@ bool Actor::restoreState(SaveGame *savedState) {
|
||||
_lastWearChore.restoreState(savedState, this);
|
||||
|
||||
if (savedState->saveMinorVersion() >= 13) {
|
||||
Common::List<Material *>::const_iterator it = _materials.begin();
|
||||
Common::List<MaterialPtr>::const_iterator it = _materials.begin();
|
||||
for (; it != _materials.end(); ++it) {
|
||||
(*it)->setActiveTexture(savedState->readLESint32());
|
||||
if (*it) {
|
||||
(*it)->setActiveTexture(savedState->readLESint32());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2411,22 +2408,28 @@ void Actor::restoreCleanBuffer() {
|
||||
}
|
||||
}
|
||||
|
||||
Material *Actor::findMaterial(const Common::String &name) {
|
||||
MaterialPtr Actor::findMaterial(const Common::String &name) {
|
||||
Common::String fixedName = g_resourceloader->fixFilename(name, false);
|
||||
Common::List<Material *>::iterator it = _materials.begin();
|
||||
Common::List<MaterialPtr>::iterator it = _materials.begin();
|
||||
for (; it != _materials.end(); ++it) {
|
||||
if ((*it)->getFilename() == fixedName) {
|
||||
return *it;
|
||||
if (*it) {
|
||||
if ((*it)->getFilename() == fixedName) {
|
||||
return *it;
|
||||
}
|
||||
} else {
|
||||
it = _materials.erase(it);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Material *Actor::loadMaterial(const Common::String &name, bool clamp) {
|
||||
Material *mat = findMaterial(name);
|
||||
MaterialPtr Actor::loadMaterial(const Common::String &name, bool clamp) {
|
||||
MaterialPtr mat = findMaterial(name);
|
||||
if (!mat) {
|
||||
mat = g_resourceloader->loadMaterial(name.c_str(), nullptr, clamp);
|
||||
// Note: We store a weak reference.
|
||||
_materials.push_back(mat);
|
||||
mat->dereference();
|
||||
}
|
||||
return mat;
|
||||
}
|
||||
|
@ -555,8 +555,8 @@ public:
|
||||
LightMode getLightMode() const { return _lightMode; }
|
||||
void setLightMode(LightMode lightMode) { _lightMode = lightMode; }
|
||||
|
||||
Material *loadMaterial(const Common::String &name, bool clamp);
|
||||
Material *findMaterial(const Common::String &name);
|
||||
ObjectPtr<Material> loadMaterial(const Common::String &name, bool clamp);
|
||||
ObjectPtr<Material> findMaterial(const Common::String &name);
|
||||
|
||||
private:
|
||||
void costumeMarkerCallback(int marker);
|
||||
@ -713,7 +713,7 @@ private:
|
||||
|
||||
LightMode _lightMode;
|
||||
|
||||
Common::List<Material *> _materials;
|
||||
Common::List<ObjectPtr<Material> > _materials;
|
||||
};
|
||||
|
||||
} // end of namespace Grim
|
||||
|
@ -283,12 +283,10 @@ Material *EMICostume::findMaterial(const Common::String &name) {
|
||||
}
|
||||
|
||||
Material *EMICostume::loadMaterial(const Common::String &name, bool clamp) {
|
||||
Material *mat = _owner->loadMaterial(name, clamp);
|
||||
MaterialPtr mat = _owner->loadMaterial(name, clamp);
|
||||
if (mat) {
|
||||
// We keep track of the list of materials per costume, so we
|
||||
// can load older savegames from a time when materials were managed
|
||||
// by EMICostume instead of Actor. Once support for older saves is
|
||||
// dropped, this list can be removed.
|
||||
// Save a reference to the material, so it will not be freed during the
|
||||
// lifetime of this costume.
|
||||
if (Common::find(_materials.begin(), _materials.end(), mat) == _materials.end())
|
||||
_materials.push_back(mat);
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ public:
|
||||
EMISkelComponent *_emiSkel;
|
||||
private:
|
||||
bool _isWearChoreActive;
|
||||
Common::List<Material *> _materials;
|
||||
Common::List<ObjectPtr<Material> > _materials;
|
||||
static bool compareChores(const Chore *c1, const Chore *c2);
|
||||
Component *loadEMIComponent(Component *parent, int parentID, const char *name, Component *prevComponent);
|
||||
void setWearChore(EMIChore *chore);
|
||||
|
Loading…
x
Reference in New Issue
Block a user