Mercurial > malikania
changeset 1:6bc25027c198
Client: do not use std::shared_ptr anymore
author | David Demelier <markand@malikania.fr> |
---|---|
date | Tue, 22 Mar 2016 21:15:41 +0100 |
parents | 8991989c4708 |
children | 2418900a1cc5 |
files | CMakeLists.txt libclient/malikania/Animation.h libclient/malikania/Animator.cpp libclient/malikania/Animator.h libclient/malikania/ClientResourcesLoader.cpp libclient/malikania/ClientResourcesLoader.h libclient/malikania/backend/sdl/WindowSdl.cpp tests/libclient/animation/main.cpp |
diffstat | 8 files changed, 280 insertions(+), 293 deletions(-) [+] |
line wrap: on
line diff
--- a/CMakeLists.txt Tue Mar 22 18:26:05 2016 +0100 +++ b/CMakeLists.txt Tue Mar 22 21:15:41 2016 +0100 @@ -26,6 +26,8 @@ "${malikania_SOURCE_DIR}/cmake/packages" ) +set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) + include(cmake/MalikaniaOptions.cmake) include(cmake/MalikaniaFunctions.cmake) include(cmake/MalikaniaVersion.cmake)
--- a/libclient/malikania/Animation.h Tue Mar 22 18:26:05 2016 +0100 +++ b/libclient/malikania/Animation.h Tue Mar 22 21:15:41 2016 +0100 @@ -69,6 +69,11 @@ }; /** + * @brief List of frames. + */ +using AnimationFrames = std::vector<AnimationFrame>; + +/** * @class Animation * @brief Animation description. * @@ -83,22 +88,20 @@ */ class Animation { private: - std::shared_ptr<Sprite> m_sprite; - std::vector<AnimationFrame> m_frames; + Sprite m_sprite; + AnimationFrames m_frames; public: /** * Create an animation. * - * @pre sprite must not be null * @param sprite the sprite image * @param frames the frames to show */ - Animation(std::shared_ptr<Sprite> sprite, std::vector<AnimationFrame> frames) noexcept + inline Animation(Sprite sprite, AnimationFrames frames) noexcept : m_sprite(std::move(sprite)) , m_frames(std::move(frames)) { - assert(m_sprite); } /** @@ -106,7 +109,17 @@ * * @return the sprite */ - inline const std::shared_ptr<Sprite> &sprite() const noexcept + inline const Sprite &sprite() const noexcept + { + return m_sprite; + } + + /** + * Overloaded function. + * + * @return the sprite + */ + inline Sprite &sprite() noexcept { return m_sprite; } @@ -116,7 +129,7 @@ * * @return the frames */ - inline const std::vector<AnimationFrame> &frames() const noexcept + inline const AnimationFrames &frames() const noexcept { return m_frames; }
--- a/libclient/malikania/Animator.cpp Tue Mar 22 18:26:05 2016 +0100 +++ b/libclient/malikania/Animator.cpp Tue Mar 22 21:15:41 2016 +0100 @@ -16,28 +16,25 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <cassert> - #include "Animation.h" #include "Animator.h" namespace malikania { -Animator::Animator(std::shared_ptr<Animation> animation) noexcept - : m_animation(std::move(animation)) +Animator::Animator(Animation &animation) noexcept + : m_animation(animation) { - assert(m_animation); } void Animator::update() noexcept { - unsigned total = m_animation->sprite()->rows() * m_animation->sprite()->columns(); + unsigned total = m_animation.sprite().rows() * m_animation.sprite().columns(); if (m_current >= total) { return; } - if (m_timer.elapsed() >= (*m_animation)[m_current].delay()) { + if (m_timer.elapsed() >= m_animation[m_current].delay()) { m_current ++; m_timer.reset(); } @@ -46,11 +43,11 @@ void Animator::draw(Window &window, const Point &point) { // TODO: assert ? - if (m_current >= m_animation->sprite()->rows() * m_animation->sprite()->columns()) { + if (m_current >= m_animation.sprite().rows() * m_animation.sprite().columns()) { return; } - m_animation->sprite()->draw(window, m_current, point); + m_animation.sprite().draw(window, m_current, point); } } // !malikania
--- a/libclient/malikania/Animator.h Tue Mar 22 18:26:05 2016 +0100 +++ b/libclient/malikania/Animator.h Tue Mar 22 21:15:41 2016 +0100 @@ -40,7 +40,7 @@ */ class Animator { private: - std::shared_ptr<Animation> m_animation; + Animation &m_animation; ElapsedTimer m_timer; unsigned m_current{0}; @@ -51,7 +51,7 @@ * @pre animation must not be null * @param animation the animation */ - Animator(std::shared_ptr<Animation> animation) noexcept; + Animator(Animation &animation) noexcept; /** * Update the animator state.
--- a/libclient/malikania/ClientResourcesLoader.cpp Tue Mar 22 18:26:05 2016 +0100 +++ b/libclient/malikania/ClientResourcesLoader.cpp Tue Mar 22 21:15:41 2016 +0100 @@ -88,8 +88,7 @@ throw std::runtime_error(id + ": not a JSON object"); } - // TODO: return all resources as shared_ptr or make a cache for sprites. - std::shared_ptr<Sprite> sprite = std::make_shared<Sprite>(loadSprite(requireString(id, value, "sprite"))); + Sprite sprite = loadSprite(requireString(id, value, "sprite")); /* Load all frames */ json::Value property = value["frames"]; @@ -98,7 +97,7 @@ throw std::runtime_error(id + ": missing 'frames' property (array expected)"); } - std::vector<AnimationFrame> frames; + AnimationFrames frames; for (auto it = property.begin(); it != property.end(); ++it) { if (!it->isObject()) {
--- a/libclient/malikania/ClientResourcesLoader.h Tue Mar 22 18:26:05 2016 +0100 +++ b/libclient/malikania/ClientResourcesLoader.h Tue Mar 22 21:15:41 2016 +0100 @@ -21,12 +21,13 @@ #include <malikania/ResourcesLoader.h> +#include "Animation.h" +#include "Image.h" +#include "Size.h" +#include "Sprite.h" + namespace malikania { -class Animation; -class Image; -class Size; -class Sprite; class Window; /**
--- a/libclient/malikania/backend/sdl/WindowSdl.cpp Tue Mar 22 18:26:05 2016 +0100 +++ b/libclient/malikania/backend/sdl/WindowSdl.cpp Tue Mar 22 21:15:41 2016 +0100 @@ -1,265 +1,240 @@ -/* - * WindowSdl.cpp -- window object (SDL2 implementation) - * - * Copyright (c) 2013-2016 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <stdexcept> - -#include <malikania/Window.h> - -namespace malikania { - -WindowSdl::WindowSdl(unsigned width, unsigned height) - : m_window(nullptr, nullptr) - , m_renderer(nullptr, nullptr) -{ - SDL_SetMainReady(); - SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO); - - m_window = WindowHandle( - SDL_CreateWindow("Malikania", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_OPENGL), - SDL_DestroyWindow - ); - - if (m_window == nullptr) { - throw std::runtime_error(SDL_GetError()); - } - - // Create renderer - m_renderer = RendererHandle( - SDL_CreateRenderer(m_window.get(), -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC), - SDL_DestroyRenderer - ); - - if (m_renderer == nullptr) { - throw std::runtime_error(SDL_GetError()); - } - - if (TTF_Init() == -1) { - throw std::runtime_error(TTF_GetError()); - } -} - -void WindowSdl::processEvents(Window &window) -{ - SDL_Event event; - - while (SDL_PollEvent(&event)) { - switch (event.type) { - case SDL_KEYUP: - window.onKeyUp(event.key.keysym.sym); - break; - // TODO continue implemanting all event possible - case SDL_KEYDOWN: - window.onKeyDown(event.key.keysym.sym); - break; - case SDL_QUIT: - window.close(); - break; - default: - break; - } - } -} - -void WindowSdl::clear() -{ - SDL_RenderClear(m_renderer.get()); -} - -void WindowSdl::update() -{ - // TO AUDIT -#if 0 - for (Refresh function : m_refreshList) { - function(); - } -#endif -} - -void WindowSdl::present() -{ - SDL_RenderPresent(m_renderer.get()); -} - -Size WindowSdl::resolution() -{ - SDL_DisplayMode current; - int width = 0; - int height = 0; - for (int i = 0; i < SDL_GetNumVideoDisplays(); i++) { - int error = SDL_GetCurrentDisplayMode(i, ¤t); - if (error == 0) { - // Get the last one - // TODO test with only one display mode, but we have to test with more than that - width = current.w; - height = current.h; - } else { - throw std::runtime_error("Could not get display mode for video display" + std::string(SDL_GetError())); - } - } - - return Size((unsigned)width, (unsigned)height); -} - -void WindowSdl::setDrawingColor(const Color &color) -{ - int error = SDL_SetRenderDrawColor(m_renderer.get(), color.red(), color.green(), color.blue(), color.alpha()); - if (error != 0) { - throw std::runtime_error("Couldn't set drawing color" + std::string(SDL_GetError())); - } -} - -void WindowSdl::drawLine(const Line &line) -{ - int error = SDL_RenderDrawLine(m_renderer.get(), line.x1(), line.y1(), line.x2(), line.y2()); - if (error != 0) { - throw std::runtime_error("Couldn't draw line" + std::string(SDL_GetError())); - } -} - -void WindowSdl::drawLines(const std::vector<Point> &points) -{ - SDL_Point sdlPoints[points.size()]; - - int i = 0; - for (const Point &point : points) { - sdlPoints[i++] = {(int)point.x(), (int)point.y()}; - } - - int error = SDL_RenderDrawLines(m_renderer.get(), sdlPoints, points.size()); - if (error != 0) { - throw std::runtime_error("Couldn't draw lines" + std::string(SDL_GetError())); - } -} - -void WindowSdl::drawPoint(const Point &point) -{ - int error = SDL_RenderDrawPoint(m_renderer.get(), point.x(), point.y()); - if (error != 0) { - throw std::runtime_error("Couldn't draw point" + std::string(SDL_GetError())); - } -} - -void WindowSdl::drawPoints(const std::vector<Point> &points) -{ - SDL_Point sdlPoints[points.size()]; - - int i = 0; - for (const Point &point : points) { - sdlPoints[i++] = {point.x(), point.y()}; - } - - int error = SDL_RenderDrawPoints(m_renderer.get(), sdlPoints, points.size()); - if (error != 0) { - throw std::runtime_error("Couldn't draw points" + std::string(SDL_GetError())); - } -} - -void WindowSdl::drawRectangle(const Rectangle &rectangle, bool filled, const malikania::Color &fillColor) -{ - SDL_Rect rect{rectangle.x(), rectangle.y(), (int)rectangle.width(), (int)rectangle.height()}; - int error = SDL_RenderDrawRect(m_renderer.get(), &rect); - if (error != 0) { - throw std::runtime_error("Couldn't draw rectangle" + std::string(SDL_GetError())); - } - if (filled) { - this->setDrawingColor(fillColor); - error = SDL_RenderFillRect(m_renderer.get(), &rect); - if (error != 0) { - throw std::runtime_error("Couldn't fill rectangle" + std::string(SDL_GetError())); - } - } -} - -void WindowSdl::drawRectangles(const std::vector<Rectangle> &rectangles, bool filled, std::vector<Color> fillColors) -{ - SDL_Rect sdlRects[rectangles.size()]; - - int i = 0; - for (const Rectangle &rectangle : rectangles) { - sdlRects[i++] = {rectangle.x(), rectangle.y(), (int)rectangle.width(), (int)rectangle.height()}; - } - - int error = SDL_RenderDrawRects(m_renderer.get(), sdlRects, rectangles.size()); - if (error != 0) { - throw std::runtime_error("Couldn't draw rectangles" + std::string(SDL_GetError())); - } - - if (filled) { - if (rectangles.size() != fillColors.size()) { - throw std::runtime_error("Couldn't fill rectangles, rectangles size and fillColors size are not the same"); - } - int j = 0; - for (Color fillColor : fillColors) { - this->setDrawingColor(fillColor); - error = SDL_RenderFillRect(m_renderer.get(), &sdlRects[j++]); - if (error != 0) { - throw std::runtime_error("Couldn't fill rectangle" + std::string(SDL_GetError())); - } - } - } -} - -/** - * TODO Add color in parameters - * @brief WindowSdl::drawText - * @param text - * @param size - */ -void WindowSdl::drawText(const std::string &text, Font &font, const Rectangle &rectangle) -{ - SDL_Color textColor = {0, 0, 0, 255}; - printf("LOL: %s\n", text.c_str()); - SDL_Surface* message = TTF_RenderUTF8_Blended(font.backend().font(), text.c_str(), textColor); - SDL_Texture* textTexture = SDL_CreateTextureFromSurface(m_renderer.get(), message); - SDL_Rect rect{rectangle.x(), rectangle.y(), (int)rectangle.width(), (int)rectangle.height()}; -#if 0 - Size screenSize = resolution(); - SDL_Rect screen{0, 0, (int)screenSize.width(), (int)screenSize.height()}; -#endif - SDL_RenderCopy(m_renderer.get(), textTexture, nullptr, &rect); - - SDL_FreeSurface(message); -} - -/** - * TODO Add color in parameters - * @brief WindowSdl::drawText - * @param text - * @param size - */ -void WindowSdl::drawText(const std::string &text, Font &font, const Point &point) -{ - SDL_Color color = {0, 0, 0, 0}; - SDL_GetRenderDrawColor(m_renderer.get(), &color.r, &color.g, &color.b, &color.a); - SDL_Surface* message = TTF_RenderUTF8_Blended(font.backend().font(), text.c_str(), color); - SDL_Texture* textTexture = SDL_CreateTextureFromSurface(m_renderer.get(), message); - SDL_Rect rect{point.x(), point.y(), message->w, message->h}; -#if 0 - Size screenSize = resolution(); - SDL_Rect screen{0, 0, (int)screenSize.width(), (int)screenSize.height()}; -#endif - SDL_RenderCopy(m_renderer.get(), textTexture, nullptr, &rect); - - SDL_FreeSurface(message); -} - -void WindowSdl::close() -{ -} - -} // !malikania +/* + * WindowSdl.cpp -- window object (SDL2 implementation) + * + * Copyright (c) 2013-2016 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <stdexcept> + +#include <malikania/Window.h> + +namespace malikania { + +WindowSdl::WindowSdl(unsigned width, unsigned height) + : m_window(nullptr, nullptr) + , m_renderer(nullptr, nullptr) +{ + SDL_SetMainReady(); + SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO); + + m_window = WindowHandle( + SDL_CreateWindow("Malikania", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_OPENGL), + SDL_DestroyWindow + ); + + if (m_window == nullptr) { + throw std::runtime_error(SDL_GetError()); + } + + // Create renderer + m_renderer = RendererHandle( + SDL_CreateRenderer(m_window.get(), -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC), + SDL_DestroyRenderer + ); + + if (m_renderer == nullptr) { + throw std::runtime_error(SDL_GetError()); + } + + if (TTF_Init() == -1) { + throw std::runtime_error(TTF_GetError()); + } +} + +void WindowSdl::processEvents(Window &window) +{ + SDL_Event event; + + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_KEYUP: + window.onKeyUp(event.key.keysym.sym); + break; + // TODO continue implemanting all event possible + case SDL_KEYDOWN: + window.onKeyDown(event.key.keysym.sym); + break; + case SDL_QUIT: + window.close(); + break; + default: + break; + } + } +} + +void WindowSdl::clear() +{ + SDL_RenderClear(m_renderer.get()); +} + +void WindowSdl::update() +{ + // TO AUDIT +#if 0 + for (Refresh function : m_refreshList) { + function(); + } +#endif +} + +void WindowSdl::present() +{ + SDL_RenderPresent(m_renderer.get()); +} + +Size WindowSdl::resolution() +{ + SDL_DisplayMode current; + int width = 0; + int height = 0; + for (int i = 0; i < SDL_GetNumVideoDisplays(); i++) { + int error = SDL_GetCurrentDisplayMode(i, ¤t); + if (error == 0) { + // Get the last one + // TODO test with only one display mode, but we have to test with more than that + width = current.w; + height = current.h; + } else { + throw std::runtime_error("Could not get display mode for video display" + std::string(SDL_GetError())); + } + } + + return Size((unsigned)width, (unsigned)height); +} + +void WindowSdl::setDrawingColor(const Color &color) +{ + int error = SDL_SetRenderDrawColor(m_renderer.get(), color.red(), color.green(), color.blue(), color.alpha()); + if (error != 0) { + throw std::runtime_error("Couldn't set drawing color" + std::string(SDL_GetError())); + } +} + +void WindowSdl::drawLine(const Line &line) +{ + if (SDL_RenderDrawLine(m_renderer.get(), line.x1(), line.y1(), line.x2(), line.y2()) != 0) { + throw std::runtime_error(SDL_GetError()); + } +} + +void WindowSdl::drawLines(const std::vector<Point> &points) +{ + std::vector<SDL_Point> sdlPoints(points.size()); + + for (unsigned i = 0; i < points.size(); ++i) { + sdlPoints[i] = SDL_Point{points[i].x(), points[i].y()}; + } + + if (SDL_RenderDrawLines(m_renderer.get(), sdlPoints.data(), sdlPoints.size()) != 0) { + throw std::runtime_error(SDL_GetError()); + } +} + +void WindowSdl::drawPoint(const Point &point) +{ + if (SDL_RenderDrawPoint(m_renderer.get(), point.x(), point.y()) != 0) { + throw std::runtime_error(SDL_GetError()); + } +} + +void WindowSdl::drawPoints(const std::vector<Point> &points) +{ + std::vector<SDL_Point> sdlPoints(points.size()); + + for (unsigned i = 0; i < points.size(); ++i) { + sdlPoints[i] = SDL_Point{points[i].x(), points[i].y()}; + } + + if (SDL_RenderDrawPoints(m_renderer.get(), sdlPoints.data(), sdlPoints.size()) != 0) { + throw std::runtime_error(SDL_GetError()); + } +} + +// TODO: not sure to keep this signature (add fillRect probably) +void WindowSdl::drawRectangle(const Rectangle &rectangle, bool filled, const malikania::Color &fillColor) +{ + SDL_Rect rect{rectangle.x(), rectangle.y(), (int)rectangle.width(), (int)rectangle.height()}; + int error = SDL_RenderDrawRect(m_renderer.get(), &rect); + if (error != 0) { + throw std::runtime_error(SDL_GetError()); + } + if (filled) { + this->setDrawingColor(fillColor); + error = SDL_RenderFillRect(m_renderer.get(), &rect); + if (error != 0) { + throw std::runtime_error(SDL_GetError()); + } + } +} + +// TODO: same as above +void WindowSdl::drawRectangles(const std::vector<Rectangle> &rectangles, bool filled, std::vector<Color> fillColors) +{ + std::vector<SDL_Rect> sdlRects(rectangles.size()); + + for (unsigned i = 0; i < rectangles.size(); ++i) { + sdlRects[i] = SDL_Rect{rectangles[i].x(), rectangles[i].y(), (int)rectangles[i].width(), (int)rectangles[i].height()}; + } + + if (SDL_RenderDrawRects(m_renderer.get(), sdlRects.data(), sdlRects.size()) != 0) { + throw std::runtime_error(SDL_GetError()); + } + + if (filled) { + if (rectangles.size() != fillColors.size()) { + throw std::runtime_error("Couldn't fill rectangles, rectangles size and fillColors size are not the same"); + } + + int j = 0; + for (Color fillColor : fillColors) { + this->setDrawingColor(fillColor); + + if (SDL_RenderFillRect(m_renderer.get(), &sdlRects[j++]) != 0) { + throw std::runtime_error("Couldn't fill rectangle" + std::string(SDL_GetError())); + } + } + } +} + +// TODO: merge this into only one function and test results. +void WindowSdl::drawText(const std::string &text, Font &font, const Rectangle &rectangle) +{ + SDL_Color color = {0, 0, 0, 255}; + SDL_Surface* message = TTF_RenderUTF8_Blended(font.backend().font(), text.c_str(), color); + SDL_Texture* texture = SDL_CreateTextureFromSurface(m_renderer.get(), message); + SDL_Rect rect{rectangle.x(), rectangle.y(), (int)rectangle.width(), (int)rectangle.height()}; + + SDL_RenderCopy(m_renderer.get(), texture, nullptr, &rect); + SDL_FreeSurface(message); +} + +void WindowSdl::drawText(const std::string &text, Font &font, const Point &point) +{ + SDL_Color color = {0, 0, 0, 0}; + SDL_GetRenderDrawColor(m_renderer.get(), &color.r, &color.g, &color.b, &color.a); + SDL_Surface* message = TTF_RenderUTF8_Blended(font.backend().font(), text.c_str(), color); + SDL_Texture* textTexture = SDL_CreateTextureFromSurface(m_renderer.get(), message); + SDL_Rect rect{point.x(), point.y(), message->w, message->h}; + + SDL_RenderCopy(m_renderer.get(), textTexture, nullptr, &rect); + SDL_FreeSurface(message); +} + +void WindowSdl::close() +{ +} + +} // !malikania
--- a/tests/libclient/animation/main.cpp Tue Mar 22 18:26:05 2016 +0100 +++ b/tests/libclient/animation/main.cpp Tue Mar 22 21:15:41 2016 +0100 @@ -80,10 +80,10 @@ try { Animation animation = m_loader.loadAnimation("animations/margins.json"); - Animator animator(std::make_shared<Animation>(animation)); + Animator animator(animation); - auto x = (400 / 2) - (animation.sprite()->cell().width() / 2); - auto y = (400 / 2) - (animation.sprite()->cell().height() / 2); + auto x = (400 / 2) - (animation.sprite().cell().width() / 2); + auto y = (400 / 2) - (animation.sprite().cell().height() / 2); while (timer.elapsed() < 8000) { window.clear();