deprecate passing callback to Animation; add an update function to Sprite for running frame by frame animation; rename log's ERROR to ERR to avoid conflict with windows.h

This commit is contained in:
ohsqueezy 2023-11-14 00:19:32 -05:00
parent 333a7b73ac
commit 110b876648
10 changed files with 57 additions and 19 deletions

View File

@ -53,7 +53,7 @@ bool Animation::playing(bool include_delay) const
return play_state && !paused && (include_delay || delay <= 0);
}
void Animation::update(float timestamp)
bool Animation::update(float timestamp)
{
timer.update(timestamp);
if (playing())
@ -81,7 +81,7 @@ void Animation::update(float timestamp)
{
overflow = 0;
}
}
}
}
return true;
} } }
return false;
}

View File

@ -24,14 +24,19 @@ private:
bool play_state = false, ending = false, paused = false;
float delay = 0.0f, overflow = 0.0f, _frame_length = 0.0f, previous_step_time = 0.0f;
Callback step = nullptr;
sb::Timer timer;
Callback step = [](){};
public:
Animation();
/*!
* @deprecated It is preferable to use the default constructor, provide a frame length using Animation::frame_length(float), and
* omit the callback function. This is because storing the callback function in this object can create copying issues when
* std::bind is used to create the callback. Instead, check the return value of Animation::update(float) to determine whether or
* not to call the desired callback externally.
*
* Create an Animation object by supplying a function and interval at which the function should run. Run Animation::update(float)
* regularly with an updated timestamp from Game::update(float), and the function will be launched automatically at the given
* interval. If the interval is omitted, the function will run every time Animation::update(float) is run.
@ -71,7 +76,17 @@ public:
void unpause();
void reset();
bool playing(bool = true) const;
void update(float timestamp);
/*!
* Update the timer and check the function's return value to determine whether a new frame of the animation should be produced.
*
* This will run the callback automatically if it is stored in this object, but the ability to store the callback in this object is deprecated and
* will be removed soon.
*
* @param timestamp Seconds since the program has started, which can be obtained from Game::update(float)
* @return True if the next frame of animation should be triggered, false otherwise
*/
bool update(float timestamp);
};

View File

@ -286,7 +286,7 @@ void Game::load_gl_context()
{
std::ostringstream message;
message << "GLEW could not initialize " << glewGetErrorString(error);
sb::Log::log(message, sb::Log::ERROR);
sb::Log::log(message, sb::Log::ERR);
}
#endif
@ -383,7 +383,7 @@ GLuint Game::load_shader(const fs::path& path, GLenum type) const
error_info.resize(max_length, 0);
glGetShaderInfoLog(shader, error_info.size(), nullptr, error_info.data());
message << "failed to compile " << path << ": " << error_info;
sb::Log::log(message, sb::Log::Level::ERROR);
sb::Log::log(message, sb::Log::Level::ERR);
return -1;
}
}
@ -409,7 +409,7 @@ bool Game::link_shader(GLuint program) const
error_info.resize(max_length, 0);
glGetProgramInfoLog(program, error_info.size(), nullptr, error_info.data());
message << "failed linking shader program " << program << ": " << error_info;
sb::Log::log(message, sb::Log::Level::ERROR);
sb::Log::log(message, sb::Log::Level::ERR);
return false;
}
}
@ -562,7 +562,7 @@ std::shared_ptr<TTF_Font> sb::Game::font(const fs::path& path, int size) const
{
std::ostringstream message;
message << "Could not load " << path;
sb::Log::log(message, sb::Log::ERROR);
sb::Log::log(message, sb::Log::ERR);
if (path != configuration()("display", "default font path").get<std::string>())
{
return this->font();

View File

@ -47,7 +47,7 @@ namespace sb
DEBUG,
INFO,
WARN,
ERROR,
ERR,
CRITICAL,
};
@ -88,7 +88,7 @@ namespace sb
* @param level message priority level
* @return a string stream containing the full message
*/
static std::ostringstream sdl_error(const std::string& message = "", const Level level = ERROR);
static std::ostringstream sdl_error(const std::string& message = "", const Level level = ERR);
};

View File

@ -117,7 +117,7 @@ const sb::Texture& sb::Model::texture(int index) const
}
else
{
return textures()[index];
return textures()[glm::mod(index, static_cast<int>(textures().size()))];
}
}
@ -129,7 +129,7 @@ sb::Texture& sb::Model::texture(int index)
}
else
{
return textures()[index];
return textures()[glm::mod(index, static_cast<int>(textures().size()))];
}
}

View File

@ -180,14 +180,17 @@ namespace sb
std::vector<sb::Texture>& textures();
/*!
* Get a constant reference to the texture at the given index. If there are no textures, an exception will be thrown.
* Get a constant reference to the texture at the given index. If there are no textures, an exception will be thrown. If the index is greater
* than the number of textures or is a negative number, modulus will be be used to wrap the value of the index to the size of the texture
* list.
*
* @param index index of texture to get
*/
const sb::Texture& texture(int index) const;
/*!
* Get the texture at the given index. If there are no textures, an exception will be thrown.
* Get the texture at the given index. If there are no textures, an exception will be thrown. If the index is greater than the number of textures
* or is a negative number, modulus will be be used to wrap the value of the index to the size of the texture list.
*
* @param index index of texture to get
*/

View File

@ -79,7 +79,7 @@ Pixels::Pixels(SDL_Renderer* renderer, SDL_Texture* texture, const Box& box) :
}
else
{
sb::Log::log("unknown texture format for loading pixels", sb::Log::Level::ERROR);
sb::Log::log("unknown texture format for loading pixels", sb::Log::Level::ERR);
}
}

View File

@ -15,6 +15,7 @@
#include "glm/glm.hpp"
#include "filesystem.hpp"
#include "Model.hpp"
#include "Animation.hpp"
namespace sb
{
@ -41,8 +42,18 @@ namespace sb
/* A sprite by definition has only one texture per draw, so keep an index to the currently active texture. */
int _texture_index = 0;
void frame_by_frame()
{
if (static_cast<std::size_t>(++_texture_index) >= plane.textures().size())
{
_texture_index = 0;
}
}
public:
sb::Animation frames;
/*!
* Construct an instance of Sprite using an existing plane object. The plane will be copied into the Sprite, so further edits must
* be made using the Sprite class.
@ -295,6 +306,15 @@ namespace sb
plane.transform(_translation * _scale * _rotation * transformation);
}
void update(const sb::Timer& timer)
{
/* Update animation */
if (frames.update(timer.stamp()))
{
frame_by_frame();
}
}
/*!
* Get the sprite's transformation from Sprite::transform(glm::mat4), which combines the translation, scale, rotation, and an
* optional arbitrary transformation, apply the given view and projection transformations, and pass the transformation to the

View File

@ -69,7 +69,7 @@ void Texture::load()
{
std::ostringstream message;
message << "Error loading texture path: " << path;
sb::Log::log(message, sb::Log::ERROR);
sb::Log::log(message, sb::Log::ERR);
}
#endif
}

View File

@ -384,7 +384,7 @@ SDL_Texture* sb::get_remapped_texture(
SDL_Texture* remapped = get_remapped_texture(renderer, base, map);
if (remapped == nullptr)
{
sb::Log::log("could not remap texture", sb::Log::ERROR);
sb::Log::log("could not remap texture", sb::Log::ERR);
return nullptr;
}
SDL_DestroyTexture(base);