Base refactor
This commit is contained in:
@ -1,16 +0,0 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "AssetManager.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
Asset::Asset(const std::string name) : name(name) {
|
||||
assertTrue(name.size() > 0, "Asset::Asset: Name cannot be empty");
|
||||
}
|
||||
|
||||
Asset::~Asset() {
|
||||
this->loaded = false;
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "state/StateEvent.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class AssetManager;
|
||||
|
||||
class Asset {
|
||||
public:
|
||||
const std::string name;
|
||||
bool_t loaded = false;
|
||||
StateEvent<> eventLoaded;
|
||||
|
||||
/**
|
||||
* Create an abstract Asset object.
|
||||
*
|
||||
* @param name Name of the asset.
|
||||
*/
|
||||
Asset(const std::string name);
|
||||
|
||||
/**
|
||||
* Virtual function that will be called by the asset manager on a
|
||||
* synchronous basis. This will only trigger if the blocks are false and
|
||||
* the loaded is also false.
|
||||
*/
|
||||
virtual void updateSync() = 0;
|
||||
|
||||
/**
|
||||
* Virtual function called by the asset manager asynchronously every tick.
|
||||
* This will only trigger if blocks are false and the loaded state is also
|
||||
* false.
|
||||
*/
|
||||
virtual void updateAsync() = 0;
|
||||
|
||||
/**
|
||||
* Dispose the asset item.
|
||||
*/
|
||||
virtual ~Asset();
|
||||
};
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "AssetManager.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void AssetManager::init() {
|
||||
|
||||
}
|
||||
|
||||
void AssetManager::update() {
|
||||
this->syncTick();
|
||||
}
|
||||
|
||||
void AssetManager::queueLoad(const std::vector<std::shared_ptr<Asset>> assets) {
|
||||
assetsToLoad.insert(this->assetsToLoad.end(), assets.begin(), assets.end());
|
||||
}
|
||||
|
||||
void AssetManager::queueLoad(const std::shared_ptr<Asset> &asset) {
|
||||
this->assetsToLoad.push_back(asset);
|
||||
}
|
||||
|
||||
void AssetManager::queueUnload(
|
||||
const std::vector<std::shared_ptr<Asset>> &assets
|
||||
) {
|
||||
std::cout <<
|
||||
"Asset list was queued to unload, but is not yet implemented" <<
|
||||
std::endl;
|
||||
assetsToUnload.insert(assetsToUnload.end(), assets.begin(), assets.end());
|
||||
}
|
||||
|
||||
void AssetManager::queueUnload(const std::shared_ptr<Asset> &asset) {
|
||||
std::cout <<
|
||||
"Asset was queued to unload, but is not yet implemented" <<
|
||||
std::endl;
|
||||
this->assetsToUnload.push_back(asset);
|
||||
}
|
||||
|
||||
void AssetManager::queueSwap(
|
||||
const std::vector<std::shared_ptr<Asset>> &newAssets,
|
||||
const std::vector<std::shared_ptr<Asset>> &oldAssets
|
||||
) {
|
||||
std::vector<std::shared_ptr<Asset>> unload;
|
||||
std::vector<std::shared_ptr<Asset>> load;
|
||||
|
||||
// Determine assets to unload.
|
||||
std::for_each(oldAssets.begin(), oldAssets.end(), [&](const auto &asset){
|
||||
auto it = std::find(newAssets.begin(), newAssets.end(), asset);
|
||||
if(it == newAssets.end()) unload.push_back(asset);
|
||||
});
|
||||
|
||||
// Determine assets to load
|
||||
std::for_each(newAssets.begin(), newAssets.end(), [&](const auto &asset){
|
||||
auto it = std::find(oldAssets.begin(), oldAssets.end(), asset);
|
||||
if(it == oldAssets.end()) load.push_back(asset);
|
||||
});
|
||||
|
||||
this->queueUnload(unload);
|
||||
this->queueLoad(load);
|
||||
}
|
||||
|
||||
void AssetManager::syncTick() {
|
||||
std::erase_if(assetsToLoad, [&](auto &asset){
|
||||
if(asset->loaded) {
|
||||
asset->eventLoaded.invoke();
|
||||
return true;
|
||||
}
|
||||
|
||||
asset->updateSync();
|
||||
asset->updateAsync();//TODO: Make Async
|
||||
|
||||
if(asset->loaded) {
|
||||
asset->eventLoaded.invoke();
|
||||
return true;
|
||||
}
|
||||
|
||||
return asset->loaded;
|
||||
});
|
||||
}
|
||||
|
||||
void AssetManager::syncLoad() {
|
||||
while(this->assetsToLoad.size() > 0) {
|
||||
this->syncTick();
|
||||
}
|
||||
}
|
||||
|
||||
AssetManager::~AssetManager() {
|
||||
this->assets.clear();
|
||||
}
|
@ -1,127 +0,0 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "Asset.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class AssetManager {
|
||||
private:
|
||||
/** List of pointers to assets, mapped by their asset key. */
|
||||
std::map<std::string, std::shared_ptr<Asset>> assets;
|
||||
std::vector<std::shared_ptr<Asset>> assetsToLoad;
|
||||
std::vector<std::shared_ptr<Asset>> assetsToUnload;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Initializes this asset manager so it can begin accepting assets.
|
||||
*/
|
||||
void init();
|
||||
|
||||
/**
|
||||
* Updates the asset manager.
|
||||
*/
|
||||
void update();
|
||||
|
||||
/**
|
||||
* Queue a loading of a list of assets. Does not actually begin loading.
|
||||
*
|
||||
* @param assets Assets to load.
|
||||
*/
|
||||
void queueLoad(const std::vector<std::shared_ptr<Asset>> assets);
|
||||
|
||||
/**
|
||||
* Queue a loading of a single asset. Does not actually begin loading.
|
||||
*
|
||||
* @param asset Asset to load.
|
||||
*/
|
||||
void queueLoad(const std::shared_ptr<Asset> &asset);
|
||||
|
||||
/**
|
||||
* Takes a list of lists to queue to unload. Does not immediately unload.
|
||||
*
|
||||
* @param assets Assets to unload.
|
||||
*/
|
||||
void queueUnload(const std::vector<std::shared_ptr<Asset>> &assets);
|
||||
|
||||
/**
|
||||
* Takes a single asset to queue to unload. Does not immediately unload.
|
||||
*
|
||||
* @param assets Assets to unload.
|
||||
*/
|
||||
void queueUnload(const std::shared_ptr<Asset> &assets);
|
||||
|
||||
/**
|
||||
* Queues load and unload based on the difference between two sets of
|
||||
* assets. This is mostly used to perform a scene change.
|
||||
*
|
||||
* @param newAssets New list of assets to maintain.
|
||||
* @param oldAssets Old list of assets to no longer maintain.
|
||||
*/
|
||||
void queueSwap(
|
||||
const std::vector<std::shared_ptr<Asset>> &newAssets,
|
||||
const std::vector<std::shared_ptr<Asset>> &oldAssets
|
||||
);
|
||||
|
||||
/**
|
||||
* Ticks the asset manager, synchronously.
|
||||
*/
|
||||
void syncTick();
|
||||
|
||||
/**
|
||||
* Loads everything that isn't loaded, blocks the current thread until
|
||||
* that has finished.
|
||||
*/
|
||||
void syncLoad();
|
||||
|
||||
/**
|
||||
* Creates and queue an asset to load.
|
||||
*
|
||||
* @param name Name of the asset to load.
|
||||
* @return The asset element to be loaded.
|
||||
*/
|
||||
template<class T>
|
||||
std::shared_ptr<T> get(std::string name) {
|
||||
assertTrue(
|
||||
name.size() > 0, "AssetManager::get: name must be greater than 0"
|
||||
);
|
||||
|
||||
auto existing = this->assets.find(name);
|
||||
if(existing != this->assets.end()) {
|
||||
return dynamic_pointer_cast<T>(existing->second);
|
||||
}
|
||||
auto asset = std::make_shared<T>(name);
|
||||
this->assets[name] = asset;
|
||||
return asset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Both gets an asset, and puts it into the load queue.
|
||||
*
|
||||
* @param name Name of the asset to load.
|
||||
* @return The asset element to be loaded.
|
||||
*/
|
||||
template<class T>
|
||||
std::shared_ptr<T> getAndLoad(std::string name) {
|
||||
auto asset = this->get<T>(name);
|
||||
this->queueLoad(asset);
|
||||
return asset;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void unload(std::shared_ptr<T> asset) {
|
||||
assertUnreachable("AssetManager::unload: NOT IMPLEMENTED");
|
||||
}
|
||||
|
||||
void unload(std::string name) {
|
||||
assertUnreachable("AssetManager::unload: NOT IMPLEMENTED");
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispose the asset manager, and all attached assets.
|
||||
*/
|
||||
~AssetManager();
|
||||
};
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
# Copyright (c) 2022 Dominic Msters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Sources
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
Asset.cpp
|
||||
IAssetLoader.cpp
|
||||
AssetManager.cpp
|
||||
)
|
||||
|
||||
# Subdirs
|
||||
add_subdirectory(assets)
|
@ -1,27 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "IAssetLoader.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
IAssetLoader::IAssetLoader(const std::string fileName) : fileName(fileName) {
|
||||
assertTrue(
|
||||
fileName.size() > 0,
|
||||
"IAssetLoader::IAssetLoader: fileName must be greater than 0"
|
||||
);
|
||||
}
|
||||
|
||||
size_t IAssetLoader::setPosition(const size_t position) {
|
||||
assertTrue(
|
||||
position >= 0,
|
||||
"IAssetLoader::setPosition: position must be greater than or equal to 0"
|
||||
);
|
||||
this->rewind();
|
||||
return this->skip(position);
|
||||
}
|
||||
|
||||
IAssetLoader::~IAssetLoader() {
|
||||
}
|
@ -1,132 +0,0 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "assert/assert.hpp"
|
||||
|
||||
#define ASSET_LOADER_BUFFER_SIZE 32768
|
||||
|
||||
#if !defined(DAWN_ASSET_LOCATION)
|
||||
#error Asset Archive Location has not been defined.
|
||||
#endif
|
||||
|
||||
namespace Dawn {
|
||||
class IAssetLoader {
|
||||
protected:
|
||||
std::string fileName;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Create a new asset loader. Asset Loaders can be used to load data from
|
||||
* a file in a myriad of ways.
|
||||
*
|
||||
* @param fileName File name of the asset that is to be loaded.
|
||||
*/
|
||||
IAssetLoader(const std::string fileName);
|
||||
|
||||
/**
|
||||
* Platform-centric method to open a file buffer to an asset.
|
||||
*/
|
||||
virtual void open() = 0;
|
||||
|
||||
/**
|
||||
* Closes the previously ppened asset.
|
||||
* @return 0 if successful, otherwise false.
|
||||
*/
|
||||
virtual int32_t close() = 0;
|
||||
|
||||
/**
|
||||
* Read bytes from buffer.
|
||||
* @param buffer Pointer to a ubyte array to buffer data into.
|
||||
* @param size Length of the data buffer (How many bytes to read).
|
||||
* @return The count of bytes read.
|
||||
*/
|
||||
virtual size_t read(uint8_t *buffer, const size_t size) = 0;
|
||||
|
||||
/**
|
||||
* Get the size of the asset.
|
||||
* @return The size of the asset in bytes.
|
||||
*/
|
||||
virtual size_t getSize() = 0;
|
||||
|
||||
/**
|
||||
* Skips the read head forward to a given position.
|
||||
*
|
||||
* @param n Count of bytes to progress the read head by.
|
||||
* @return Count of bytes progressed.
|
||||
*/
|
||||
virtual size_t skip(const size_t n) = 0;
|
||||
|
||||
/**
|
||||
* Rewind the read head to the beginning of the file.
|
||||
*/
|
||||
virtual void rewind() = 0;
|
||||
|
||||
/**
|
||||
* Sets the absolute position of the read head within the buffer of the
|
||||
* file.
|
||||
*
|
||||
* @param absolutePosition Absolute position to set the read head to.
|
||||
*/
|
||||
size_t setPosition(const size_t absolutePosition);
|
||||
|
||||
/**
|
||||
* Returns the current position of the read head.
|
||||
*
|
||||
* @return The current read head position.
|
||||
*/
|
||||
virtual size_t getPosition() = 0;
|
||||
|
||||
/**
|
||||
* Run a callback for each byte within the asset. The callback will
|
||||
* receive each byte individually.
|
||||
*
|
||||
* @tparam T Type of instance to run callback against.
|
||||
* @param instance Instance of the object to run the callback against.
|
||||
* @param callback Callback method on the class to run the callback for.
|
||||
* @return The count of bytes read.
|
||||
*/
|
||||
template<class T>
|
||||
size_t loadBufferedCallback(
|
||||
std::function<bool_t(uint8_t n)> callback
|
||||
) {
|
||||
uint8_t buffer[1024];
|
||||
size_t read, length;
|
||||
int32_t i;
|
||||
bool_t result;
|
||||
|
||||
assertNotNull(callback, "Callback cannot be null.");
|
||||
|
||||
// Open the buffer.
|
||||
this->open();
|
||||
|
||||
// Reset length size
|
||||
length = 0;
|
||||
|
||||
// Buffer from input
|
||||
while((read = this->read(buffer, 1024)) != 0) {
|
||||
for(i = 0; i < read; i++) {
|
||||
result = callback(buffer[i]);
|
||||
if(!result) {
|
||||
length += i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!result) break;
|
||||
length += read;
|
||||
}
|
||||
|
||||
// Close the buffer
|
||||
this->close();
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup the asset loader.
|
||||
*/
|
||||
virtual ~IAssetLoader();
|
||||
};
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "AudioAsset.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
AudioAsset::AudioAsset(const std::string name) :
|
||||
Asset(name),
|
||||
loader(name + ".audio")
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void AudioAsset::updateSync() {
|
||||
if(this->state != AUDIO_ASSET_LOAD_STATE_DATA_READ) return;
|
||||
|
||||
// THIS WILL DEFINITELY CHANGE
|
||||
this->state = AUDIO_ASSET_LOAD_STATE_COMPLETE;
|
||||
this->loaded = true;
|
||||
}
|
||||
|
||||
void AudioAsset::updateAsync() {
|
||||
if(this->state != AUDIO_ASSET_LOAD_STATE_INITIAL) return;
|
||||
char *start, *end;
|
||||
char buffer[1024];
|
||||
|
||||
// Open asset for reading
|
||||
this->state = AUDIO_ASSET_LOAD_STATE_OPENING;
|
||||
this->loader.open();
|
||||
|
||||
// Parse header data.
|
||||
this->state = AUDIO_ASSET_LOAD_STATE_READING_HEADER;
|
||||
this->loader.read((uint8_t *)buffer, 1024);
|
||||
|
||||
// Channel count
|
||||
this->state = AUDIO_ASSET_LOAD_STATE_READING_CHANNEL_COUNT;
|
||||
start = buffer;
|
||||
end = strchr(start, '|');
|
||||
*end = '\0';
|
||||
this->channelCount = atoi(start);
|
||||
assertTrue(this->channelCount > 0, "Channel count must be greater than 0");
|
||||
|
||||
// Sample Rate
|
||||
this->state = AUDIO_ASSET_LOAD_STATE_READING_SAMPLE_RATE;
|
||||
start = end + 1;
|
||||
end = strchr(start, '|');
|
||||
*end = '\0';
|
||||
this->sampleRate = (uint32_t)strtoul(start, NULL, 10);
|
||||
assertTrue(this->sampleRate > 0, "Sample rate must be greater than 0");
|
||||
|
||||
// Number of samples per channel
|
||||
this->state = AUDIO_ASSET_LOAD_STATE_READING_SAMPLES_PER_CHANNEL;
|
||||
start = end + 1;
|
||||
end = strchr(start, '|');
|
||||
*end = '\0';
|
||||
this->samplesPerChannel = atoi(start);
|
||||
assertTrue(
|
||||
this->samplesPerChannel > 0,
|
||||
"Samples per channel must be greater than 0"
|
||||
);
|
||||
|
||||
// Total Data Length
|
||||
this->state = AUDIO_ASSET_LOAD_STATE_READING_DATA_LENGTH;
|
||||
start = end + 1;
|
||||
end = strchr(start, '|');
|
||||
*end = '\0';
|
||||
this->bufferSize = (size_t)atoll(start);
|
||||
assertTrue(this->bufferSize > 0, "Buffer size must be greater than 0");
|
||||
|
||||
// Determine frame size
|
||||
this->frameSize = sizeof(int16_t) * this->channelCount;
|
||||
|
||||
// Indicated start of data
|
||||
this->state = AUDIO_ASSET_LOAD_STATE_DATA_READ;
|
||||
this->bufferStart = end - buffer;
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "../Asset.hpp"
|
||||
#include "asset/AssetLoader.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class AudioSource;
|
||||
|
||||
enum AudioAssetLoadState {
|
||||
AUDIO_ASSET_LOAD_STATE_INITIAL,
|
||||
AUDIO_ASSET_LOAD_STATE_OPENING,
|
||||
AUDIO_ASSET_LOAD_STATE_READING_HEADER,
|
||||
AUDIO_ASSET_LOAD_STATE_READING_CHANNEL_COUNT,
|
||||
AUDIO_ASSET_LOAD_STATE_READING_SAMPLE_RATE,
|
||||
AUDIO_ASSET_LOAD_STATE_READING_SAMPLES_PER_CHANNEL,
|
||||
AUDIO_ASSET_LOAD_STATE_READING_DATA_LENGTH,
|
||||
AUDIO_ASSET_LOAD_STATE_DATA_READ,
|
||||
AUDIO_ASSET_LOAD_STATE_COMPLETE
|
||||
};
|
||||
|
||||
class AudioAsset : public Asset {
|
||||
protected:
|
||||
AssetLoader loader;
|
||||
enum AudioAssetLoadState state = AUDIO_ASSET_LOAD_STATE_INITIAL;
|
||||
|
||||
int32_t channelCount;
|
||||
uint32_t sampleRate;
|
||||
int32_t samplesPerChannel;
|
||||
size_t bufferSize;
|
||||
size_t bufferStart;
|
||||
size_t frameSize;
|
||||
|
||||
public:
|
||||
AudioAsset(const std::string name);
|
||||
|
||||
void updateSync() override;
|
||||
void updateAsync() override;
|
||||
|
||||
friend class AudioSource;
|
||||
};
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
# Copyright (c) 2022 Dominic Msters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Sources
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
AudioAsset.cpp
|
||||
LanguageAsset.cpp
|
||||
TextureAsset.cpp
|
||||
TrueTypeAsset.cpp
|
||||
)
|
@ -1,86 +0,0 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "LanguageAsset.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
LanguageAsset::LanguageAsset(const std::string name) :
|
||||
Asset(name),
|
||||
loader(name + ".language")
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void LanguageAsset::updateSync() {
|
||||
|
||||
}
|
||||
|
||||
void LanguageAsset::updateAsync() {
|
||||
assertTrue(
|
||||
this->state == LANGUAGE_ASSET_LOAD_STATE_INITIAL,
|
||||
"State must be initial"
|
||||
);
|
||||
|
||||
// Open Asset
|
||||
this->state = LANGUAGE_ASSET_LOAD_STATE_OPENING;
|
||||
this->loader.open();
|
||||
|
||||
// Get Length
|
||||
size_t len = this->loader.getSize();
|
||||
|
||||
// Create buffer
|
||||
this->state = LANGUAGE_ASSET_LOAD_STATE_CREATING_BUFFER;
|
||||
size_t position = 0;
|
||||
|
||||
// Loop over CSV
|
||||
while(position < len) {
|
||||
this->loader.read(buffer, 1024);
|
||||
|
||||
// Get strings
|
||||
uint8_t *keyStart = buffer;
|
||||
uint8_t *keyEnd = (uint8_t*)strchr((char*)keyStart, '|');
|
||||
*keyEnd = '\0';
|
||||
uint8_t *valueStart = keyEnd + 1;
|
||||
uint8_t *valueEnd = (uint8_t*)strchr((char*)valueStart, '|');
|
||||
|
||||
// Load value positions
|
||||
struct AssetLanguageValue value;
|
||||
value.begin = position + (size_t)(valueStart - buffer);
|
||||
value.length = (size_t)(valueEnd - valueStart);
|
||||
|
||||
// Prepare for next string.
|
||||
position = position + (size_t)(valueEnd - buffer + 1);
|
||||
this->loader.setPosition(position);
|
||||
|
||||
// Store strings.
|
||||
std::string key((char *)keyStart);
|
||||
this->values[key] = value;
|
||||
}
|
||||
|
||||
this->state = LANGUAGE_ASSET_LOAD_STATE_READY_TO_READ;
|
||||
this->loaded = true;
|
||||
}
|
||||
|
||||
std::string LanguageAsset::getValue(const std::string key) {
|
||||
assertTrue(
|
||||
this->state == LANGUAGE_ASSET_LOAD_STATE_READY_TO_READ,
|
||||
"State must be LANGUAGE_ASSET_LOAD_STATE_READY_TO_READ"
|
||||
);
|
||||
assertMapHasKey(this->values, key, "Key does not exist");
|
||||
assertTrue(
|
||||
this->values[key].begin >= 0 && this->values[key].length > 0,
|
||||
"Value is invalid"
|
||||
);
|
||||
|
||||
// Get the positions
|
||||
struct AssetLanguageValue value = this->values[key];
|
||||
|
||||
this->loader.setPosition(value.begin);
|
||||
this->loader.read(buffer, value.length);
|
||||
buffer[value.length] = '\0';
|
||||
|
||||
return std::string((char *)buffer, value.length + 1);
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "../Asset.hpp"
|
||||
#include "asset/AssetLoader.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
struct AssetLanguageValue {
|
||||
size_t begin;
|
||||
size_t length;
|
||||
};
|
||||
|
||||
enum LangageAssetLoadState {
|
||||
LANGUAGE_ASSET_LOAD_STATE_INITIAL,
|
||||
LANGUAGE_ASSET_LOAD_STATE_OPENING,
|
||||
LANGUAGE_ASSET_LOAD_STATE_CREATING_BUFFER,
|
||||
LANGUAGE_ASSET_LOAD_STATE_READY_TO_READ
|
||||
};
|
||||
|
||||
class LanguageAsset : public Asset {
|
||||
protected:
|
||||
AssetLoader loader;
|
||||
enum LangageAssetLoadState state = LANGUAGE_ASSET_LOAD_STATE_INITIAL;
|
||||
std::map<std::string, struct AssetLanguageValue> values;
|
||||
uint8_t buffer[1024];
|
||||
|
||||
public:
|
||||
LanguageAsset(const std::string name);
|
||||
void updateSync() override;
|
||||
void updateAsync() override;
|
||||
std::string getValue(const std::string key);
|
||||
};
|
||||
}
|
@ -1,136 +0,0 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "TextureAsset.hpp"
|
||||
#include "util/memory.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
TextureAsset::TextureAsset(const std::string name) :
|
||||
Asset(name),
|
||||
loader(name + ".texture"),
|
||||
texture()
|
||||
{
|
||||
}
|
||||
|
||||
void TextureAsset::updateSync() {
|
||||
if(this->state != TEXTURE_ASSET_LOAD_STATE_SYNC_HANDOFF) return;
|
||||
|
||||
this->state = TEXTURE_ASSET_LOAD_STATE_BUFFERING_TEXTURE;
|
||||
this->texture.setSize(
|
||||
this->width, this->height, this->format, TEXTURE_DATA_FORMAT_UNSIGNED_BYTE
|
||||
);
|
||||
this->texture.buffer(this->colors);
|
||||
|
||||
this->texture.wrapModeX = this->wrapModeX;
|
||||
this->texture.wrapModeY = this->wrapModeY;
|
||||
this->texture.filterModeMin = this->filterModeMin;
|
||||
this->texture.filterModeMag = this->filterModeMag;
|
||||
|
||||
this->state = TEXTURE_ASSET_LOAD_STATE_COMPLETE;
|
||||
this->loaded = true;
|
||||
}
|
||||
|
||||
void TextureAsset::updateAsync() {
|
||||
if(this->state != TEXTURE_ASSET_LOAD_STATE_INITIAL) return;
|
||||
this->state = TEXTURE_ASSET_LOAD_STATE_OPENING;
|
||||
this->loader.open();
|
||||
this->buffer = memoryAllocate<uint8_t>(this->loader.getSize());
|
||||
this->loader.read(this->buffer, this->loader.getSize());
|
||||
this->loader.close();
|
||||
this->state = TEXTURE_ASSET_LOAD_STATE_PARSING_HEADER;
|
||||
|
||||
// Parse header data.
|
||||
char integer[256];
|
||||
size_t j = 0, i = 0;
|
||||
enum TextureAssetHeaderParseState parseState =
|
||||
TEXTURE_ASSET_HEADER_PARSE_STATE_VERSION
|
||||
;
|
||||
while(true) {
|
||||
if(parseState == TEXTURE_ASSET_HEADER_PARSE_STATE_END) break;
|
||||
|
||||
auto c = this->buffer[i++];
|
||||
if(c != '|') {
|
||||
integer[j++] = c;
|
||||
continue;
|
||||
}
|
||||
|
||||
integer[j] = '\0';
|
||||
|
||||
switch(parseState) {
|
||||
case TEXTURE_ASSET_HEADER_PARSE_STATE_VERSION: {
|
||||
auto compared = strcmp(integer, "DT_2.00");
|
||||
assertTrue(compared == 0, "Invalid version");
|
||||
j = 0;
|
||||
parseState = TEXTURE_ASSET_HEADER_PARSE_STATE_WIDTH;
|
||||
break;
|
||||
}
|
||||
|
||||
case TEXTURE_ASSET_HEADER_PARSE_STATE_WIDTH: {
|
||||
this->width = atoi(integer);
|
||||
assertTrue(this->width > 0, "Invalid width");
|
||||
j = 0;
|
||||
parseState = TEXTURE_ASSET_HEADER_PARSE_STATE_HEIGHT;
|
||||
break;
|
||||
}
|
||||
|
||||
case TEXTURE_ASSET_HEADER_PARSE_STATE_HEIGHT: {
|
||||
this->height = atoi(integer);
|
||||
assertTrue(this->height > 0, "Invalid height");
|
||||
j = 0;
|
||||
parseState = TEXTURE_ASSET_HEADER_PARSE_STATE_FORMAT;
|
||||
break;
|
||||
}
|
||||
|
||||
case TEXTURE_ASSET_HEADER_PARSE_STATE_FORMAT: {
|
||||
this->format = (enum TextureFormat)atoi(integer);
|
||||
j = 0;
|
||||
parseState = TEXTURE_ASSET_HEADER_PARSE_STATE_WRAP_MODE_X;
|
||||
break;
|
||||
}
|
||||
|
||||
case TEXTURE_ASSET_HEADER_PARSE_STATE_WRAP_MODE_X: {
|
||||
this->wrapModeX = (enum TextureWrapMode)atoi(integer);
|
||||
j = 0;
|
||||
parseState = TEXTURE_ASSET_HEADER_PARSE_STATE_WRAP_MODE_Y;
|
||||
break;
|
||||
}
|
||||
|
||||
case TEXTURE_ASSET_HEADER_PARSE_STATE_WRAP_MODE_Y: {
|
||||
this->wrapModeY = (enum TextureWrapMode)atoi(integer);
|
||||
j = 0;
|
||||
parseState = TEXTURE_ASSET_HEADER_PARSE_STATE_FILTER_MODE_MIN;
|
||||
break;
|
||||
}
|
||||
|
||||
case TEXTURE_ASSET_HEADER_PARSE_STATE_FILTER_MODE_MIN: {
|
||||
this->filterModeMin = (enum TextureFilterMode)atoi(integer);
|
||||
j = 0;
|
||||
parseState = TEXTURE_ASSET_HEADER_PARSE_STATE_FILTER_MODE_MAG;
|
||||
break;
|
||||
}
|
||||
|
||||
case TEXTURE_ASSET_HEADER_PARSE_STATE_FILTER_MODE_MAG: {
|
||||
this->filterModeMag = (enum TextureFilterMode)atoi(integer);
|
||||
j = 0;
|
||||
parseState = TEXTURE_ASSET_HEADER_PARSE_STATE_END;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
assertUnreachable("Invalid parse state");
|
||||
}
|
||||
}
|
||||
|
||||
this->colors = (uint8_t*)((void *)(this->buffer + i));
|
||||
this->state = TEXTURE_ASSET_LOAD_STATE_SYNC_HANDOFF;
|
||||
}
|
||||
|
||||
TextureAsset::~TextureAsset() {
|
||||
if(this->buffer != nullptr) {
|
||||
memoryFree(this->buffer);
|
||||
this->buffer = nullptr;
|
||||
}
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "../Asset.hpp"
|
||||
#include "asset/AssetLoader.hpp"
|
||||
#include "display/Texture.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
enum TextureAssetHeaderParseState {
|
||||
TEXTURE_ASSET_HEADER_PARSE_STATE_VERSION,
|
||||
TEXTURE_ASSET_HEADER_PARSE_STATE_WIDTH,
|
||||
TEXTURE_ASSET_HEADER_PARSE_STATE_HEIGHT,
|
||||
TEXTURE_ASSET_HEADER_PARSE_STATE_FORMAT,
|
||||
TEXTURE_ASSET_HEADER_PARSE_STATE_WRAP_MODE_X,
|
||||
TEXTURE_ASSET_HEADER_PARSE_STATE_WRAP_MODE_Y,
|
||||
TEXTURE_ASSET_HEADER_PARSE_STATE_FILTER_MODE_MIN,
|
||||
TEXTURE_ASSET_HEADER_PARSE_STATE_FILTER_MODE_MAG,
|
||||
TEXTURE_ASSET_HEADER_PARSE_STATE_END
|
||||
};
|
||||
|
||||
enum TextureAssetLoadState {
|
||||
TEXTURE_ASSET_LOAD_STATE_INITIAL,
|
||||
TEXTURE_ASSET_LOAD_STATE_OPENING,
|
||||
TEXTURE_ASSET_LOAD_STATE_PARSING_HEADER,
|
||||
TEXTURE_ASSET_LOAD_STATE_SYNC_HANDOFF,
|
||||
TEXTURE_ASSET_LOAD_STATE_BUFFERING_TEXTURE,
|
||||
TEXTURE_ASSET_LOAD_STATE_COMPLETE,
|
||||
};
|
||||
|
||||
class TextureAsset : public Asset {
|
||||
protected:
|
||||
AssetLoader loader;
|
||||
uint8_t *buffer = nullptr;
|
||||
int32_t width = -1, height = -1;
|
||||
uint8_t *colors;
|
||||
enum TextureAssetLoadState state = TEXTURE_ASSET_LOAD_STATE_INITIAL;
|
||||
enum TextureFormat format;
|
||||
enum TextureWrapMode wrapModeX;
|
||||
enum TextureWrapMode wrapModeY;
|
||||
enum TextureFilterMode filterModeMin;
|
||||
enum TextureFilterMode filterModeMag;
|
||||
|
||||
public:
|
||||
Texture texture;
|
||||
|
||||
/**
|
||||
* Constructs a texture asset loader. You should instead use the parent
|
||||
* asset managers' abstracted load method
|
||||
*
|
||||
* @param name File name asset to load, omitting the extension.
|
||||
*/
|
||||
TextureAsset(const std::string name);
|
||||
|
||||
void updateSync() override;
|
||||
void updateAsync() override;
|
||||
|
||||
/**
|
||||
* Dispose / Cleanup the texture asset. Will also dispose the underlying
|
||||
* texture itself.
|
||||
*/
|
||||
~TextureAsset();
|
||||
};
|
||||
}
|
@ -1,239 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "TrueTypeAsset.hpp"
|
||||
#include "asset/AssetManager.hpp"
|
||||
#include "util/memory.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
TrueTypeAsset::TrueTypeAsset(const std::string name) :
|
||||
Asset(name),
|
||||
loader(name + ".truetype")
|
||||
{
|
||||
this->locks.onLockRemoved = [&](usagelockid_t id){
|
||||
auto texture = this->textureByLock[id];
|
||||
|
||||
assertNotNull(texture, "Texture cannot be null");
|
||||
|
||||
std::vector<usagelockid_t> &lbt = this->locksByTexture[texture];
|
||||
auto it0 = std::find(lbt.begin(), lbt.end(), id);
|
||||
assertTrue(it0 != lbt.end(), "Could not remove locksByTexture[texture]");
|
||||
lbt.erase(it0);
|
||||
|
||||
auto it1 = this->textureByLock.find(id);
|
||||
assertTrue(
|
||||
it1 != this->textureByLock.end(), "Could not remove textureByLock"
|
||||
);
|
||||
this->textureByLock.erase(it1);
|
||||
|
||||
if(lbt.empty()) {
|
||||
auto it2 = locksByTexture.find(texture);
|
||||
assertTrue(
|
||||
it2 != locksByTexture.end(), "Could not remove locksByTexture"
|
||||
);
|
||||
locksByTexture.erase(it2);
|
||||
|
||||
std::erase_if(textureByStyle, [&](const auto &item){
|
||||
auto const& [key, value] = item;
|
||||
return value == texture;
|
||||
});
|
||||
|
||||
std::erase(textures, texture);
|
||||
delete texture;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void TrueTypeAsset::updateSync() {
|
||||
|
||||
}
|
||||
|
||||
void TrueTypeAsset::updateAsync() {
|
||||
if(this->state != TRUE_TYPE_ASSET_STATE_INITIAL) return;
|
||||
|
||||
this->state = TRUE_TYPE_ASSET_STATE_OPEN;
|
||||
this->loader.open();
|
||||
|
||||
this->state = TRUE_TYPE_ASSET_STATE_VALIDATE_HEADER;
|
||||
|
||||
uint8_t buffer[64];
|
||||
this->loader.rewind();
|
||||
size_t read = this->loader.read(buffer, sizeof(char) * 6);
|
||||
assertTrue(read == (6 * sizeof(char)), "Could not read header");
|
||||
buffer[6] = '\0';
|
||||
|
||||
// Confirm "DE_TTF"
|
||||
assertTrue(
|
||||
std::string((char *)buffer) == "DE_TTF",
|
||||
"Header is invalid (Missing DE_TTF)"
|
||||
);
|
||||
|
||||
// Vertical bar
|
||||
this->loader.read(buffer, 1);
|
||||
assertTrue(
|
||||
buffer[0] == '|',
|
||||
"Header is invalid (Missing first vertical bar)"
|
||||
);
|
||||
|
||||
// Read version
|
||||
this->state = TRUE_TYPE_ASSET_STATE_VALIDATE_VERSION;
|
||||
read = this->loader.read(buffer, sizeof(char) * 5);
|
||||
assertTrue(buffer[0] == '3', "Version is invalid 3");
|
||||
assertTrue(buffer[1] == '.', "Version is invalid .");
|
||||
assertTrue(buffer[2] == '0', "Version is invalid 0(1)");
|
||||
assertTrue(buffer[3] == '0', "Version is invalid 0(2)");
|
||||
assertTrue(
|
||||
buffer[4] == '|',
|
||||
"Version is invalid (Missing second vertical bar)"
|
||||
);
|
||||
|
||||
// Read the count of font styles / variants.
|
||||
size_t styleListBegin = this->loader.getPosition();
|
||||
this->state = TRUE_TYPE_ASSET_STATE_READ_VARIANT_COUNT;
|
||||
read = this->loader.read(buffer, 64);
|
||||
assertTrue(read > 0, "Could not read variant count");
|
||||
|
||||
// Get position of vertical bar.
|
||||
size_t i = 0;
|
||||
while(buffer[i] != '|' && i < 64) i++;
|
||||
assertTrue(buffer[i] == '|', "Could not find vertical bar");
|
||||
styleListBegin += i + 1;
|
||||
buffer[i] = '\0';
|
||||
|
||||
int32_t count = atoi((char *)buffer);
|
||||
assertTrue(count > 0, "Invalid variant count");
|
||||
|
||||
// Now begin parsing each font style.
|
||||
this->state = TRUE_TYPE_ASSET_STATE_READ_VARIANT;
|
||||
assetStyles.clear();
|
||||
while(assetStyles.size() != count) {
|
||||
struct TrueTypeAssetStyle style;
|
||||
|
||||
// Buffer
|
||||
this->loader.setPosition(styleListBegin);
|
||||
read = this->loader.read(buffer, 32);
|
||||
assertTrue(read == 32, "Could not read variant");
|
||||
|
||||
// Read style
|
||||
i = 0;
|
||||
while(buffer[i] != ':' && i < 64) i++;
|
||||
buffer[i] = '\0';
|
||||
style.style = atoi((char *)buffer);
|
||||
styleListBegin += i + 1;
|
||||
|
||||
// Buffer
|
||||
this->loader.setPosition(styleListBegin);
|
||||
read = this->loader.read(buffer, 32);
|
||||
assertTrue(read == 32, "Could not read variant style");
|
||||
|
||||
// Read length
|
||||
i = 0;
|
||||
while(buffer[i] != '|' && i < 64) i++;
|
||||
buffer[i] = '\0';
|
||||
styleListBegin += i + 1;
|
||||
style.dataSize = atol((char *)buffer);
|
||||
|
||||
// Push
|
||||
assetStyles.push_back(style);
|
||||
}
|
||||
|
||||
// Now we are at the first byte of the first style.
|
||||
this->state = TRUE_TYPE_ASSET_STATE_ADJUSTING_OFFSETS;
|
||||
std::for_each(
|
||||
assetStyles.begin(),
|
||||
assetStyles.end(),
|
||||
[&](struct TrueTypeAssetStyle &style){
|
||||
style.dataOffset = styleListBegin;
|
||||
styleListBegin += style.dataSize;
|
||||
styleListBegin += 1;
|
||||
}
|
||||
);
|
||||
|
||||
// Init FreeType
|
||||
this->state = TRUE_TYPE_ASSET_STATE_INIT_FREETYPE;
|
||||
int32_t ret = FT_Init_FreeType(&fontLibrary);
|
||||
assertTrue(ret == 0, "Could not init FreeType");
|
||||
|
||||
// Done parsing!
|
||||
this->state = TRUE_TYPE_ASSET_STATE_READY;
|
||||
this->loaded = true;
|
||||
}
|
||||
|
||||
usagelockid_t TrueTypeAsset::lock(const struct TrueTypeFaceTextureStyle style) {
|
||||
assertTrue(this->state == TRUE_TYPE_ASSET_STATE_READY, "Asset is not ready");
|
||||
|
||||
// Try and find an existing texture that matches this style
|
||||
auto it = this->textureByStyle.find(style);
|
||||
TrueTypeFaceTexture *texture = nullptr;
|
||||
|
||||
if(it == this->textureByStyle.end()) {
|
||||
// Does not exist, Find asset style
|
||||
auto itAssetStyle = std::find_if(
|
||||
assetStyles.begin(),
|
||||
assetStyles.end(),
|
||||
[&](const struct TrueTypeAssetStyle &assetStyle) {
|
||||
return assetStyle.style == style.style;
|
||||
}
|
||||
);
|
||||
assertTrue(
|
||||
itAssetStyle != this->assetStyles.end(),
|
||||
"Could not find asset style"
|
||||
);
|
||||
|
||||
// Create and read buffer.
|
||||
uint8_t *dataBuffer = memoryAllocate<uint8_t>(itAssetStyle->dataSize);
|
||||
this->loader.rewind();
|
||||
this->loader.setPosition(itAssetStyle->dataOffset);
|
||||
auto read = this->loader.read(dataBuffer, itAssetStyle->dataSize);
|
||||
assertTrue(read == itAssetStyle->dataSize, "Could not read data");
|
||||
|
||||
// Create the face
|
||||
FT_Face face;
|
||||
auto ret = FT_New_Memory_Face(
|
||||
this->fontLibrary,
|
||||
(FT_Byte*)dataBuffer,
|
||||
itAssetStyle->dataSize,
|
||||
0,
|
||||
&face
|
||||
);
|
||||
assertTrue(ret == 0, "Could not create face");
|
||||
texture = new TrueTypeFaceTexture(face, style);
|
||||
memoryFree(dataBuffer);
|
||||
|
||||
this->textures.push_back(texture);
|
||||
this->textureByStyle[style] = texture;
|
||||
} else {
|
||||
// Exists
|
||||
texture = it->second;
|
||||
}
|
||||
|
||||
auto lock = this->locks.createLock();
|
||||
this->textureByLock[lock] = texture;
|
||||
this->locksByTexture[texture].push_back(lock);
|
||||
return lock;
|
||||
}
|
||||
|
||||
TrueTypeFaceTexture * TrueTypeAsset::getTexture(const usagelockid_t id) {
|
||||
auto it = this->textureByLock.find(id);
|
||||
assertTrue(it != this->textureByLock.end(), "Could not find texture");
|
||||
return it->second;
|
||||
}
|
||||
|
||||
void TrueTypeAsset::unlock(const usagelockid_t id) {
|
||||
this->locks.removeLock(id);
|
||||
}
|
||||
|
||||
TrueTypeAsset::~TrueTypeAsset() {
|
||||
std::for_each(
|
||||
this->textures.begin(),
|
||||
this->textures.end(),
|
||||
[](TrueTypeFaceTexture *texture){
|
||||
delete texture;
|
||||
}
|
||||
);
|
||||
|
||||
FT_Done_FreeType(this->fontLibrary);
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "../Asset.hpp"
|
||||
#include "asset/AssetLoader.hpp"
|
||||
#include "util/flag.hpp"
|
||||
#include "display/font/truetype/TrueTypeFaceTexture.hpp"
|
||||
#include "util/UsageLock.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
enum TrueTypeAssetState {
|
||||
TRUE_TYPE_ASSET_STATE_INITIAL,
|
||||
TRUE_TYPE_ASSET_STATE_OPEN,
|
||||
TRUE_TYPE_ASSET_STATE_VALIDATE_HEADER,
|
||||
TRUE_TYPE_ASSET_STATE_VALIDATE_VERSION,
|
||||
TRUE_TYPE_ASSET_STATE_READ_VARIANT_COUNT,
|
||||
TRUE_TYPE_ASSET_STATE_READ_VARIANT,
|
||||
TRUE_TYPE_ASSET_STATE_ADJUSTING_OFFSETS,
|
||||
TRUE_TYPE_ASSET_STATE_INIT_FREETYPE,
|
||||
TRUE_TYPE_ASSET_STATE_READY
|
||||
};
|
||||
|
||||
struct TrueTypeAssetStyle {
|
||||
flag_t style;
|
||||
size_t dataSize;
|
||||
size_t dataOffset;
|
||||
};
|
||||
|
||||
class TrueTypeAsset : public Asset {
|
||||
protected:
|
||||
UsageLock locks;
|
||||
AssetLoader loader;
|
||||
FT_Library fontLibrary;
|
||||
enum TrueTypeAssetState state = TRUE_TYPE_ASSET_STATE_INITIAL;
|
||||
std::vector<struct TrueTypeAssetStyle> assetStyles;
|
||||
std::vector<TrueTypeFaceTexture*> textures;
|
||||
std::map<usagelockid_t, TrueTypeFaceTexture*> textureByLock;
|
||||
std::map<struct TrueTypeFaceTextureStyle, TrueTypeFaceTexture*>
|
||||
textureByStyle
|
||||
;
|
||||
std::map<TrueTypeFaceTexture*, std::vector<usagelockid_t>> locksByTexture;
|
||||
|
||||
public:
|
||||
TrueTypeAsset(const std::string name);
|
||||
void updateSync() override;
|
||||
void updateAsync() override;
|
||||
|
||||
/**
|
||||
* Create a lock for a specific style. Locks will ensure that the font is
|
||||
* held loaded until it is no longer required.
|
||||
*
|
||||
* @param style Style to lock.
|
||||
* @return A unique lock ID for this style.
|
||||
*/
|
||||
usagelockid_t lock(const struct TrueTypeFaceTextureStyle style);
|
||||
|
||||
/**
|
||||
* Get a texture by a previous lock ID.
|
||||
*
|
||||
* @param lock Lock to get the texture of.
|
||||
* @return Matching texture by this ID.
|
||||
*/
|
||||
TrueTypeFaceTexture * getTexture(const usagelockid_t lock);
|
||||
|
||||
/**
|
||||
* Releases a previously held font lock.
|
||||
*
|
||||
* @param lock Lock to release/unlock.
|
||||
*/
|
||||
void unlock(const usagelockid_t lock);
|
||||
|
||||
~TrueTypeAsset();
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user