aboutsummaryrefslogtreecommitdiff
path: root/extension/src/openvic-extension/singletons/AssetManager.hpp
blob: 96cb8809d7521355d39fcb5ceb6511ac7ace5aa0 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#pragma once

#include <godot_cpp/classes/atlas_texture.hpp>
#include <godot_cpp/classes/font_file.hpp>
#include <godot_cpp/classes/image_texture.hpp>
#include <godot_cpp/classes/style_box_texture.hpp>
#include <godot_cpp/core/class_db.hpp>
#include <godot_cpp/variant/vector2.hpp>

#include <openvic-simulation/interface/GFXSprite.hpp>

#include "openvic-extension/classes/GFXSpriteTexture.hpp"

namespace OpenVic {
   class AssetManager : public godot::Object {
      GDCLASS(AssetManager, godot::Object)

      static inline AssetManager* _singleton = nullptr;

   public:
      enum LoadFlags {
         LOAD_FLAG_NONE          = 0,
         LOAD_FLAG_CACHE_IMAGE   = 1 << 0,
         LOAD_FLAG_CACHE_TEXTURE = 1 << 1,
         LOAD_FLAG_FLIP_Y        = 1 << 2
      };

      constexpr friend LoadFlags operator|(LoadFlags lhs, LoadFlags rhs) {
         return static_cast<LoadFlags>(static_cast<int>(lhs) | static_cast<int>(rhs));
      }

   private:
      struct image_asset_t {
         std::optional<godot::Ref<godot::Image>> image;
         std::optional<godot::Ref<godot::ImageTexture>> texture;
      };
      /* deque_ordered_map to avoid the need to reallocate. */
      using image_asset_map_t = deque_ordered_map<godot::StringName, image_asset_t>;
      using font_map_t = deque_ordered_map<godot::StringName, godot::Ref<godot::FontFile>>;

      image_asset_map_t image_assets;
      font_map_t fonts;

      static godot::Ref<godot::Image> _load_image(godot::StringName const& path, bool flip_y);

   protected:
      static void _bind_methods();

   public:
      static AssetManager* get_singleton();

      AssetManager();
      ~AssetManager();

      /* Search for and load an image at the specified path relative to the game defines, first checking the AssetManager's
       * image cache in case it has already been loaded, and returning nullptr if image loading fails. If the cache image
       * load flag is set then the loaded image will be stored in the AssetManager's image cache for future access; if the
       * flip y load flag is set then the image will be flipped vertically before being returned (if the image is already
       * in the cache then no flipping will occur, regardless of whether it was orginally flipped or not). */
      godot::Ref<godot::Image> get_image(godot::StringName const& path, LoadFlags load_flags = LOAD_FLAG_CACHE_IMAGE);

      /* Create a texture from an image found at the specified path relative to the game defines, fist checking the
       * AssetManager's texture cache in case it has already been loaded, and returning nullptr if image loading or texture
       * creation fails. If the cache image load flag is set then the loaded image will be stored in the AssetManager's
       * image cache for future access; if the cache texture load flag is set then the created texture will be stored in the
       * AssetManager's texture cache for future access; if the flip y load flag is set then the image will be flipped
       * vertically before being used to create the texture (if the image is already in the cache then no flipping will
       * occur, regardless of whether it was orginally flipped or not). */
      godot::Ref<godot::ImageTexture> get_texture(
         godot::StringName const& path, LoadFlags load_flags = LOAD_FLAG_CACHE_TEXTURE
      );

      static godot::Ref<godot::StyleBoxTexture> make_stylebox_texture(
         godot::Ref<godot::Texture2D> const& texture, godot::Vector2 const& border = {}
      );

      /* Search for and load a font with the specified name from the game defines' font directory, first checking the
       * AssetManager's font cache in case it has already been loaded, and returning nullptr if font loading fails. */
      godot::Ref<godot::FontFile> get_font(godot::StringName const& name);

   private:
      godot::Ref<GFXSpriteTexture> PROPERTY(currency_texture_big);    // 32x32
      godot::Ref<GFXSpriteTexture> PROPERTY(currency_texture_medium); // 24x24
      godot::Ref<GFXSpriteTexture> PROPERTY(currency_texture_small);  // 16x16

   public:
      godot::Error preload_textures();

      /* Get the largest currency texture with height less than the specified font height. */
      godot::Ref<GFXSpriteTexture> const& get_currency_texture(real_t height) const;
   };
}

VARIANT_ENUM_CAST(OpenVic::AssetManager::LoadFlags);