Skip to content

Commit

Permalink
Fixed|Client: Avoid crash when save contains animator state
Browse files Browse the repository at this point in the history
If an object being loaded does not have a 3D model animator, but the savegame does, the animator state should be read but discarded.

Previously it was just trying to read into a nullptr, causing a crash.
  • Loading branch information
skyjake committed Oct 20, 2018
1 parent f6b3a41 commit ad296ce
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 17 deletions.
1 change: 1 addition & 0 deletions doomsday/apps/client/include/render/stateanimator.h
Expand Up @@ -49,6 +49,7 @@ class StateAnimator : public de::ModelDrawable::Animator,
DENG2_ERROR(DefinitionError);

public:
StateAnimator();
StateAnimator(de::DotPath const &id, Model const &model);

Model const &model() const;
Expand Down
40 changes: 24 additions & 16 deletions doomsday/apps/client/src/render/stateanimator.cpp
Expand Up @@ -202,24 +202,27 @@ DENG2_PIMPL(StateAnimator)

Impl(Public *i, DotPath const &assetId) : Base(i)
{
initVariables(assetId);

// Set up the model drawing parameters.
if (!self().model().passes.isEmpty())
if (!assetId.isEmpty())
{
appearance.drawPasses = &self().model().passes;
initVariables(assetId);

// Set up the model drawing parameters.
if (!self().model().passes.isEmpty())
{
appearance.drawPasses = &self().model().passes;
}
appearance.programCallback = [this] (GLProgram &program, ModelDrawable::ProgramBinding binding)
{
bindUniforms(program,
binding == ModelDrawable::AboutToBind? Bind : Unbind);
};
appearance.passCallback = [this] (ModelDrawable::Pass const &pass, ModelDrawable::PassState state)
{
bindPassUniforms(*self().model().currentProgram(),
pass.name,
state == ModelDrawable::PassBegun? Bind : Unbind);
};
}
appearance.programCallback = [this] (GLProgram &program, ModelDrawable::ProgramBinding binding)
{
bindUniforms(program,
binding == ModelDrawable::AboutToBind? Bind : Unbind);
};
appearance.passCallback = [this] (ModelDrawable::Pass const &pass, ModelDrawable::PassState state)
{
bindPassUniforms(*self().model().currentProgram(),
pass.name,
state == ModelDrawable::PassBegun? Bind : Unbind);
};
}

~Impl()
Expand Down Expand Up @@ -575,6 +578,11 @@ DENG2_PIMPL(StateAnimator)
}
};

StateAnimator::StateAnimator()
: ModelDrawable::Animator(Impl::Sequence::make)
, d(new Impl(this, {}))
{}

StateAnimator::StateAnimator(DotPath const &id, Model const &model)
: ModelDrawable::Animator(model, Impl::Sequence::make)
, d(new Impl(this, id))
Expand Down
10 changes: 9 additions & 1 deletion doomsday/apps/client/src/world/clientmobjthinkerdata.cpp
Expand Up @@ -333,7 +333,15 @@ void ClientMobjThinkerData::operator << (Reader &from)
if (flags & Impl::HasAnimator) // Animator
{
d->initOnce();
from >> *d->animator;
if (d->animator)
{
from >> *d->animator;
}
else
{
render::StateAnimator temp;
from >> temp; // Not used.
}
}
}

Expand Down

0 comments on commit ad296ce

Please sign in to comment.