Added ostd::AsyncJob class
This commit is contained in:
parent
42a2ee330b
commit
367ad5c92a
10 changed files with 313 additions and 17 deletions
|
|
@ -86,6 +86,7 @@ list(APPEND OGFX_SOURCE_FILES
|
|||
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/Image.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/WindowBaseOutputHandler.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/PixelRenderer.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/Animation.cpp
|
||||
)
|
||||
list(APPEND TEST_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/test.cpp
|
||||
|
|
|
|||
BIN
extra/res/test.png
Normal file
BIN
extra/res/test.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 251 KiB |
|
|
@ -1 +1 @@
|
|||
2009
|
||||
2020
|
||||
|
|
|
|||
97
src/ogfx/Animation.cpp
Normal file
97
src/ogfx/Animation.cpp
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
#include "Animation.hpp"
|
||||
#include <ostd/math/Random.hpp>
|
||||
|
||||
namespace ogfx
|
||||
{
|
||||
Animation::Animation(void)
|
||||
{
|
||||
create(0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
Animation::Animation(int frames, int columns, int rows, int frame_width, int frame_height)
|
||||
{
|
||||
create(frames, columns, rows, frame_width, frame_height);
|
||||
}
|
||||
|
||||
Animation::Animation(AnimationData& ad)
|
||||
{
|
||||
create(ad);
|
||||
}
|
||||
|
||||
void Animation::create(AnimationData& ad)
|
||||
{
|
||||
create(ad.length, ad.columns, ad.rows, ad.frame_width, ad.frame_height);
|
||||
m_backwards = ad.backwards;
|
||||
m_still = ad.still;
|
||||
m_column_offset = ad.column_offset;
|
||||
m_row_offset = ad.row_offset;
|
||||
m_frame_time = ad.speed;
|
||||
m_random = false;
|
||||
}
|
||||
|
||||
void Animation::create(int frames, int columns, int rows, int frame_width, int frame_height)
|
||||
{
|
||||
m_frames = frames;
|
||||
m_columns = columns;
|
||||
m_frame_width = frame_width;
|
||||
m_frame_height = frame_height;
|
||||
m_rows = rows;
|
||||
m_frame_time = 5;
|
||||
m_current_time = 0;
|
||||
m_current_frame = 0;
|
||||
m_backwards = false;
|
||||
m_back = false;
|
||||
m_still = false;
|
||||
m_random = false;
|
||||
m_column_offset = 0;
|
||||
m_row_offset = 0;
|
||||
}
|
||||
|
||||
void Animation::resetAnimation(void)
|
||||
{
|
||||
m_current_frame = 0;
|
||||
m_current_time = 0;
|
||||
}
|
||||
|
||||
void Animation::update(void)
|
||||
{
|
||||
if (m_current_time++ > m_frame_time && !m_still)
|
||||
{
|
||||
m_current_time = 0;
|
||||
if (m_random)
|
||||
{
|
||||
m_current_frame = ostd::Random::geti32(0, m_frames);
|
||||
}
|
||||
else if (m_backwards)
|
||||
{
|
||||
if (!m_back && m_current_frame >= m_frames - 1)
|
||||
{
|
||||
m_back = true;
|
||||
m_current_frame--;
|
||||
}
|
||||
else if (!m_back)
|
||||
m_current_frame++;
|
||||
else if (m_back && m_current_frame <= 0)
|
||||
{
|
||||
m_back = false;
|
||||
m_current_frame++;
|
||||
}
|
||||
else if (m_back)
|
||||
m_current_frame--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_current_frame++ >= m_frames - 1)
|
||||
m_current_frame = 0;
|
||||
}
|
||||
}
|
||||
else if (m_still)
|
||||
m_current_frame = 1; //TODO: Hardcoded value
|
||||
int x = ((m_current_frame % m_columns) + m_column_offset) * m_frame_width;
|
||||
int y = m_row_offset * m_frame_height;
|
||||
if (m_rows > 1)
|
||||
y = ((m_current_frame / m_columns) + m_row_offset) * m_frame_height;
|
||||
|
||||
m_frame_rect = { static_cast<float>(x), static_cast<float>(y), static_cast<float>(m_frame_width), static_cast<float>(m_frame_height) };
|
||||
}
|
||||
}
|
||||
98
src/ogfx/Animation.hpp
Normal file
98
src/ogfx/Animation.hpp
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
#pragma once
|
||||
|
||||
#include <ostd/data_types/Types.hpp>
|
||||
#include <ostd/math/Geometry.hpp>
|
||||
#include <ogfx/Image.hpp>
|
||||
|
||||
namespace ogfx
|
||||
{
|
||||
class Animation
|
||||
{
|
||||
public: struct AnimationData {
|
||||
int32_t length;
|
||||
int32_t speed;
|
||||
int32_t still_frame;
|
||||
|
||||
int32_t row_offset;
|
||||
int32_t column_offset;
|
||||
|
||||
int32_t rows;
|
||||
int32_t columns;
|
||||
|
||||
int32_t frame_width;
|
||||
int32_t frame_height;
|
||||
|
||||
bool still;
|
||||
bool backwards;
|
||||
bool random;
|
||||
|
||||
AnimationData(void)
|
||||
{
|
||||
length = 3;
|
||||
speed = 10;
|
||||
row_offset = 0;
|
||||
column_offset = 0;
|
||||
rows = 1;
|
||||
columns = 3;
|
||||
frame_width = 32;
|
||||
frame_height = 32;
|
||||
still = false;
|
||||
backwards = true;
|
||||
random = false;
|
||||
still_frame = 1;
|
||||
}
|
||||
};
|
||||
public:
|
||||
Animation(void);
|
||||
Animation(int32_t frames, int32_t columns, int32_t rows, int32_t frame_width, int32_t frame_height);
|
||||
Animation(AnimationData& ad);
|
||||
void create(int32_t frames, int32_t columns, int32_t rows, int32_t frame_width, int32_t frame_height);
|
||||
void create(AnimationData& ad);
|
||||
void update(void);
|
||||
void resetAnimation(void);
|
||||
|
||||
inline void setFrameNumber(int32_t n) { m_frames = n; }
|
||||
inline void setColumnNumber(int32_t n) { m_columns = n; }
|
||||
inline void setBackwards(bool b) { m_backwards = b; }
|
||||
inline void setSpeed(int32_t d) { m_frame_time = d; }
|
||||
inline void setColumnOffset(int32_t o) { m_column_offset = o; }
|
||||
inline void setRowOffset(int32_t o) { m_row_offset = o; }
|
||||
inline void setStill(bool s) { m_still = s; }
|
||||
inline void setSpriteSheet(const Image& img) { m_spriteSheet = &img; }
|
||||
|
||||
inline int32_t getFrameNumber(void) const { return m_frames; }
|
||||
inline int32_t getColumnNumber(void) const { return m_columns; }
|
||||
inline bool getBackwards(void) const { return m_backwards; }
|
||||
inline int32_t getDelay(void) const { return m_frame_time; }
|
||||
inline int32_t getColumnOffset(void) const { return m_column_offset; }
|
||||
inline int32_t getRowOffset(void) const { return m_row_offset; }
|
||||
inline bool isStill(void) const { return m_still; }
|
||||
inline ostd::Rectangle getFrameRect(void) const { return m_frame_rect; }
|
||||
inline const Image& getSpriteSheet(void) const { return (m_spriteSheet != nullptr ? *m_spriteSheet : InvalidImage); }
|
||||
inline bool hasImage(void) const { return m_spriteSheet != nullptr; }
|
||||
|
||||
private:
|
||||
const Image* m_spriteSheet { nullptr };
|
||||
inline static const Image InvalidImage;
|
||||
|
||||
int32_t m_frames;
|
||||
int32_t m_rows;
|
||||
int32_t m_columns;
|
||||
int32_t m_frame_width;
|
||||
int32_t m_frame_height;
|
||||
|
||||
int32_t m_column_offset;
|
||||
int32_t m_row_offset;
|
||||
|
||||
int32_t m_frame_time;
|
||||
int32_t m_current_time;
|
||||
int32_t m_current_frame;
|
||||
|
||||
bool m_backwards;
|
||||
bool m_back;
|
||||
bool m_still;
|
||||
bool m_random;
|
||||
|
||||
ostd::Rectangle m_frame_rect;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
#include "BasicRenderer.hpp"
|
||||
#include "WindowBase.hpp"
|
||||
#include <SDL2/SDL_rect.h>
|
||||
|
||||
namespace ogfx
|
||||
{
|
||||
|
|
@ -22,7 +23,7 @@ namespace ogfx
|
|||
m_ttfr.setFontSize(fontSize);
|
||||
}
|
||||
|
||||
void BasicRenderer2D::drawImage(const ogfx::Image& image, const ostd::Vec2& position)
|
||||
void BasicRenderer2D::drawImage(const ogfx::Image& image, const ostd::Vec2& position, const ostd::Rectangle& rect)
|
||||
{
|
||||
if (!m_initialized) return;
|
||||
if (!image.isLoaded()) return;
|
||||
|
|
@ -31,7 +32,28 @@ namespace ogfx
|
|||
texr.y = position.y;
|
||||
texr.w = image.getSize().x;
|
||||
texr.h = image.getSize().y;
|
||||
SDL_Rect srcRect;
|
||||
srcRect.x = rect.x;
|
||||
srcRect.y = rect.y;
|
||||
srcRect.w = rect.w;
|
||||
srcRect.h = rect.w;
|
||||
if (srcRect.x == 0 && srcRect.y == 0 && srcRect.w == 0 && srcRect.h == 0)
|
||||
SDL_RenderCopy(m_window->getSDLRenderer(), image.getSDLTexture(), nullptr, &texr);
|
||||
else
|
||||
{
|
||||
texr.w = srcRect.w;
|
||||
texr.h = srcRect.h;
|
||||
SDL_RenderCopy(m_window->getSDLRenderer(), image.getSDLTexture(), &srcRect, &texr);
|
||||
}
|
||||
}
|
||||
|
||||
void BasicRenderer2D::drawAnimation(const Animation& anim, const ostd::Vec2& position)
|
||||
{
|
||||
if (!m_initialized) return;
|
||||
if (!anim.hasImage()) return;
|
||||
const auto& img = anim.getSpriteSheet();
|
||||
if (!img.isLoaded() || !img.isValid()) return;
|
||||
drawImage(img, position, anim.getFrameRect());
|
||||
}
|
||||
|
||||
void BasicRenderer2D::drawString(const ostd::String& str, const ostd::Vec2& position, const ostd::Color& color, int32_t fontSize)
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "Animation.hpp"
|
||||
#include <ogfx/FontUtils.hpp>
|
||||
#include <ostd/math/Geometry.hpp>
|
||||
#include <ogfx/Image.hpp>
|
||||
|
|
@ -40,7 +41,8 @@ namespace ogfx
|
|||
void setFont(const ostd::String& fontFilePath);
|
||||
void setFontSize(int32_t fontSize);
|
||||
|
||||
void drawImage(const ogfx::Image& image, const ostd::Vec2& position);
|
||||
void drawImage(const ogfx::Image& image, const ostd::Vec2& position, const ostd::Rectangle& rect = { 0, 0, 0, 0 });
|
||||
void drawAnimation(const Animation& anim, const ostd::Vec2& position);
|
||||
|
||||
void drawString(const ostd::String& str, const ostd::Vec2& position, const ostd::Color& color, int32_t fontSize = 0);
|
||||
void drawCenteredString(const ostd::String& str, const ostd::Vec2& center, const ostd::Color& color, int32_t fontSize = 0);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "Image.hpp"
|
||||
#include "io/Logger.hpp"
|
||||
#include <SDL2/SDL_render.h>
|
||||
#include <ogfx/BasicRenderer.hpp>
|
||||
#include <ogfx/WindowBase.hpp>
|
||||
|
|
@ -19,6 +20,11 @@ namespace ogfx
|
|||
if (!gfx.isInitialized())
|
||||
return *this; //TODO: Error
|
||||
m_sdl_texture = IMG_LoadTexture(gfx.getWindow().getSDLRenderer(), filePath.c_str());
|
||||
if (!m_sdl_texture)
|
||||
{
|
||||
OX_ERROR("Failed to load Image: %s", IMG_GetError());
|
||||
return *this;
|
||||
}
|
||||
SDL_QueryTexture(m_sdl_texture, nullptr, nullptr, &m_width, &m_height);
|
||||
m_loaded = true;
|
||||
setTypeName("ogfx::Image");
|
||||
|
|
|
|||
61
src/ostd/utils/Async.hpp
Normal file
61
src/ostd/utils/Async.hpp
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
#pragma once
|
||||
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <atomic>
|
||||
#include <optional>
|
||||
|
||||
namespace ostd
|
||||
{
|
||||
template<typename T>
|
||||
class AsyncJob
|
||||
{
|
||||
public:
|
||||
AsyncJob() = default;
|
||||
|
||||
// Start a new job (callable must return T)
|
||||
template<typename Callable, typename... Args>
|
||||
void start(Callable&& func, Args&&... args)
|
||||
{
|
||||
// Reset state
|
||||
m_done.store(false);
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
m_result.reset();
|
||||
}
|
||||
|
||||
// Launch detached worker thread
|
||||
std::thread([this, func = std::forward<Callable>(func), ... args = std::forward<Args>(args)]() mutable {
|
||||
T value = func(args...);
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
m_result = std::move(value);
|
||||
}
|
||||
m_done.store(true);
|
||||
}).detach();
|
||||
}
|
||||
|
||||
inline bool isReady(void) const { return m_done.load(); }
|
||||
|
||||
// Retrieve the result (only valid if is_ready() == true)
|
||||
inline T get(void)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
return *m_result;
|
||||
}
|
||||
|
||||
// Retrieve result as optional (safe even if not ready)
|
||||
std::optional<T> tryGet(void)
|
||||
{
|
||||
if (!m_done.load())
|
||||
return std::nullopt;
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
return m_result;
|
||||
}
|
||||
|
||||
private:
|
||||
std::atomic<bool> m_done { false };
|
||||
std::optional<T> m_result;
|
||||
mutable std::mutex m_mutex;
|
||||
};
|
||||
}
|
||||
|
|
@ -23,6 +23,8 @@
|
|||
// #include <ostd/Logger.hpp>
|
||||
// #include <ostd/Console.hpp>
|
||||
|
||||
#include "Image.hpp"
|
||||
#include "utils/Utils.hpp"
|
||||
#include <ogfx/WindowBase.hpp>
|
||||
#include <ogfx/RawTextInput.hpp>
|
||||
#include <ostd/ostd.hpp>
|
||||
|
|
@ -48,6 +50,10 @@ class Window : public ogfx::WindowBase
|
|||
m_textInput.setEventListener(m_sigHandler);
|
||||
// m_textInput.setCharacterFilter(m_numCharFilter);
|
||||
m_textInput.getTheme().extraPaddingTop = 3;
|
||||
|
||||
m_testImg.loadFromFile("res/test.png", m_gfx);
|
||||
out.p("Image loaded: ").p(STR_BOOL(m_testImg.isLoaded())).nl();
|
||||
out.p(" ").p(m_testImg.getSize().x).nl();
|
||||
}
|
||||
|
||||
inline void handleSignal(ostd::tSignal& signal) override
|
||||
|
|
@ -79,6 +85,7 @@ class Window : public ogfx::WindowBase
|
|||
inline void onRender(void) override
|
||||
{
|
||||
m_textInput.render(m_gfx);
|
||||
// m_gfx.drawImage(m_testImg, { 0, 0 });´
|
||||
}
|
||||
|
||||
inline void onFixedUpdate(double frameTime_s) override
|
||||
|
|
@ -96,6 +103,8 @@ class Window : public ogfx::WindowBase
|
|||
ogfx::BasicRenderer2D m_gfx;
|
||||
ogfx::gui::RawTextInputEventListener m_sigHandler;
|
||||
ogfx::gui::RawTextInputNumberCharacterFilter m_numCharFilter;
|
||||
|
||||
ogfx::Image m_testImg;
|
||||
};
|
||||
|
||||
// void test2(const std::string& str) {}
|
||||
|
|
|
|||
Loading…
Reference in a new issue