File: CustomAsset.h

package info (click to toggle)
dolphin-emu 2512%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 76,328 kB
  • sloc: cpp: 499,023; ansic: 119,674; python: 6,547; sh: 2,338; makefile: 1,093; asm: 726; pascal: 257; javascript: 183; perl: 97; objc: 75; xml: 30
file content (115 lines) | stat: -rw-r--r-- 3,261 bytes parent folder | download
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// Copyright 2023 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

#include "Common/CommonTypes.h"
#include "VideoCommon/Assets/CustomAssetLibrary.h"

#include <atomic>
#include <memory>
#include <mutex>

namespace VideoCommon
{
// An abstract class that provides operations for loading
// data from a 'CustomAssetLibrary'
class CustomAsset
{
public:
  using ClockType = std::chrono::steady_clock;
  using TimeType = ClockType::time_point;

  CustomAsset(std::shared_ptr<CustomAssetLibrary> library,
              const CustomAssetLibrary::AssetID& asset_id, u64 session_id);
  virtual ~CustomAsset() = default;
  CustomAsset(const CustomAsset&) = delete;
  CustomAsset(CustomAsset&&) = delete;
  CustomAsset& operator=(const CustomAsset&) = delete;
  CustomAsset& operator=(CustomAsset&&) = delete;

  // Loads the asset from the library returning the number of bytes loaded
  std::size_t Load();

  // Unloads the asset data, resets the bytes loaded and
  // returns the number of bytes unloaded
  std::size_t Unload();

  // Returns the time that the data was last loaded
  TimeType GetLastLoadedTime() const;

  // Returns an id that uniquely identifies this asset
  const CustomAssetLibrary::AssetID& GetAssetId() const;

  // Returns an id that is unique to this game session
  // This is a faster form to hash and can be used
  // as an index
  std::size_t GetHandle() const;

protected:
  const std::shared_ptr<CustomAssetLibrary> m_owning_library;

private:
  virtual CustomAssetLibrary::LoadInfo LoadImpl(const CustomAssetLibrary::AssetID& asset_id) = 0;
  virtual void UnloadImpl() = 0;
  CustomAssetLibrary::AssetID m_asset_id;
  std::size_t m_handle;

  mutable std::mutex m_info_lock;
  std::size_t m_bytes_loaded = 0;
  std::atomic<TimeType> m_last_loaded_time = {};
};

// An abstract class that is expected to
// be the base class for all assets
// It provides a simple interface for
// verifying that an asset data of type
// 'UnderlyingType' is loaded by
// checking against 'GetData()'
template <typename UnderlyingType>
class CustomLoadableAsset : public CustomAsset
{
public:
  using CustomAsset::CustomAsset;

  // Callees should understand that the type returned is
  // a local copy and 'GetData()' needs to be called
  // to ensure the latest copy is available if
  // they want to handle reloads
  [[nodiscard]] std::shared_ptr<UnderlyingType> GetData() const
  {
    std::lock_guard lk(m_data_lock);
    if (m_loaded)
      return m_data;
    return nullptr;
  }

protected:
  bool m_loaded = false;
  mutable std::mutex m_data_lock;
  std::shared_ptr<UnderlyingType> m_data;

private:
  void UnloadImpl() override
  {
    std::lock_guard lk(m_data_lock);
    m_loaded = false;
    m_data.reset();
  }
};

// A helper struct that contains
// an asset with a last cached write time
// This can be used to determine if the asset
// has diverged from the last known state
// To know if it is time to update other dependencies
// based on the asset data
// TODO C++20: use a 'derived_from' concept against 'CustomAsset' when available
template <typename AssetType>
struct CachedAsset
{
  std::shared_ptr<AssetType> m_asset;
  CustomAsset::TimeType m_cached_write_time;
};

}  // namespace VideoCommon