Skip to content

Commit

Permalink
AssertResolutionResolver refactoring.
Browse files Browse the repository at this point in the history
  • Loading branch information
syoyo committed Sep 21, 2023
1 parent d000dd5 commit 70ffec0
Show file tree
Hide file tree
Showing 4 changed files with 297 additions and 95 deletions.
67 changes: 47 additions & 20 deletions examples/file_format/file-format-example.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,38 @@
std::map<std::string, float> g_map;

//
// We provide two APIs
//
// - File system API(for AssetResolution::openAsset)
// - Create on-memory file(data)
// To read asset in custom format(and in custom file system), this example provides
//
// - AssetResolution handler(for AssetResolution::open_asset)
// - Create on-memory asset system
// - File format API(read/write data with custom format)
// - Simple 4 byte binary(float value)
//

// File system APIs
static int MyFSizeData(const char *asset_name, uint64_t *nbytes, std::string *err, void *userdata) {
static int MyARResolve(const char *asset_name, const std::vector<std::string> &search_paths, std::string *resolved_asset_name, std::string *err, void *userdata) {
(void)err;
(void)userdata;
(void)search_paths;

if (!asset_name) {
return -2; // err
}

if (!resolved_asset_name) {
return -2; // err
}

if (g_map.count(asset_name)) {
(*resolved_asset_name) = asset_name;
return 0; // OK
}

return -1; // failed to resolve.
}


// AssetResoltion handlers
static int MyARSize(const char *asset_name, uint64_t *nbytes, std::string *err, void *userdata) {
(void)userdata;

if (!asset_name) {
Expand All @@ -43,7 +67,7 @@ static int MyFSizeData(const char *asset_name, uint64_t *nbytes, std::string *er
return 0; // OK
}

int MyFSReadData(const char *asset_name, uint64_t req_nbytes, uint8_t *out_buf,
int MyARRead(const char *asset_name, uint64_t req_nbytes, uint8_t *out_buf,
uint64_t *nbytes, std::string *err, void *userdata) {

if (!asset_name) {
Expand Down Expand Up @@ -72,30 +96,26 @@ int MyFSReadData(const char *asset_name, uint64_t req_nbytes, uint8_t *out_buf,
return 0;
}

//
//
return -1;
}

//
// custom File-format APIs.
//
static bool MyCheck(const uint8_t *addr, const size_t nbytes, std::string *warn, std::string *err, void *user_data) {
static bool MyCheck(const tinyusdz::Asset &asset, std::string *warn, std::string *err, void *user_data) {
return true;
}

static bool MyRead(const uint8_t *addr, const size_t nbytes, tinyusdz::PrimSpec &ps/* inout */, std::string *warn, std::string *err, void *user_data) {
static bool MyRead(const tinyusdz::Asset &asset, tinyusdz::PrimSpec &ps/* inout */, std::string *warn, std::string *err, void *user_data) {

if (!addr) {
if (asset.size() != 4) {
return false;
}

if (nbytes != 4) {
return false;
}


float val;
memcpy(&val, addr, 4);
memcpy(&val, asset.data(), 4);

tinyusdz::Attribute attr;
attr.set_value(val);
Expand All @@ -107,7 +127,7 @@ static bool MyRead(const uint8_t *addr, const size_t nbytes, tinyusdz::PrimSpec
return true;
}

static bool MyWrite(const tinyusdz::PrimSpec &ps, std::vector<uint8_t> *data_out, std::string *warn, std::string *err, void *user_data) {
static bool MyWrite(const tinyusdz::PrimSpec &ps, tinyusdz::Asset *asset_out, std::string *warn, std::string *err, void *user_data) {
// TOOD
return false;
}
Expand Down Expand Up @@ -146,8 +166,15 @@ int main(int argc, char **argv) {
exit(-1);
}

// dummy Asset resolver.
tinyusdz::AssetResolutionResolver resolver;
// Register filesystem handler for `.my` asset.
tinyusdz::AssetResolutionHandler ar_handler;
ar_handler.resolve_fun = MyARResolve;
ar_handler.size_fun = MyARSize;
ar_handler.read_fun = MyARRead;
ar_handler.write_fun = nullptr; // not used in this example.
ar_handler.userdata = nullptr; // not used in this example;
resolver.register_asset_resolution_handler("my", ar_handler);

tinyusdz::ReferencesCompositionOptions options;
options.fileformats["my"] = my_handler;
Expand All @@ -158,8 +185,8 @@ int main(int argc, char **argv) {
std::cerr << "Failed to composite `references`: " << err << "\n";
return -1;
}


// Print USD scene as Ascii.
std::cout << composited_layer << "\n";

Expand Down
119 changes: 119 additions & 0 deletions src/asset-resolution.cc
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
// SPDX-License-Identifier: Apache 2.0
// Copyright 2022 - Present, Light Transport Entertainment, Inc.
#include <cassert>
#include <iostream>

#include "asset-resolution.hh"
#include "common-macros.inc"
#include "io-util.hh"
#include "value-pprint.hh"
#include "str-util.hh"

namespace tinyusdz {

Expand All @@ -27,17 +29,134 @@ std::string AssetResolutionResolver::search_paths_str() const {
bool AssetResolutionResolver::find(const std::string &assetPath) const {
DCOUT("search_paths = " << _search_paths);
DCOUT("assetPath = " << assetPath);

std::string ext = io::GetFileExtension(assetPath);

if (_asset_resolution_handlers.count(ext)) {
if (_asset_resolution_handlers.at(ext).resolve_fun && _asset_resolution_handlers.at(ext).size_fun) {
std::string resolvedPath;
std::string err;

// Use custom handler's userdata
void *userdata = _asset_resolution_handlers.at(ext).userdata;

int ret = _asset_resolution_handlers.at(ext).resolve_fun(assetPath.c_str(), _search_paths, &resolvedPath, &err, userdata);
if (ret != 0) {
return false;
}

uint64_t sz{0};
ret = _asset_resolution_handlers.at(ext).size_fun(resolvedPath.c_str(), &sz, &err, userdata);
if (ret != 0) {
return false;
}

return sz > 0;

} else {
DCOUT("Either Resolve function or Size function is nullptr. Fallback to built-in file handler.");
}
}

// TODO: Cache resolition.
std::string fpath = io::FindFile(assetPath, _search_paths);
return fpath.size();
}

std::string AssetResolutionResolver::resolve(
const std::string &assetPath) const {

std::string ext = io::GetFileExtension(assetPath);

if (_asset_resolution_handlers.count(ext)) {
if (_asset_resolution_handlers.at(ext).resolve_fun) {
std::string resolvedPath;
std::string err;

// Use custom handler's userdata
void *userdata = _asset_resolution_handlers.at(ext).userdata;

int ret = _asset_resolution_handlers.at(ext).resolve_fun(assetPath.c_str(), _search_paths, &resolvedPath, &err, userdata);
if (ret != 0) {
return std::string();
}

return resolvedPath;

} else {
DCOUT("Resolve function is nullptr. Fallback to built-in file handler.");
}
}

DCOUT("search_paths = " << _search_paths);
DCOUT("assetPath = " << assetPath);
// TODO: Cache resolition.
return io::FindFile(assetPath, _search_paths);
}

bool AssetResolutionResolver::open_asset(const std::string &resolvedPath, const std::string &assetPath,
Asset *asset_out, std::string *warn, std::string *err) {


if (!asset_out) {
if (err) {
(*err) = "`asset` arg is nullptr.";
}
return false;
}

(void)assetPath;
(void)warn;

std::string ext = io::GetFileExtension(resolvedPath);

if (_asset_resolution_handlers.count(ext)) {
if (_asset_resolution_handlers.at(ext).size_fun && _asset_resolution_handlers.at(ext).read_fun) {

// Use custom handler's userdata
void *userdata = _asset_resolution_handlers.at(ext).userdata;

// Get asset size.
uint64_t sz{0};
int ret = _asset_resolution_handlers.at(ext).size_fun(resolvedPath.c_str(), &sz, err, userdata);
if (ret != 0) {
return false;
}

tinyusdz::Asset asset;
asset.resize(sz);

uint64_t read_size{0};

ret = _asset_resolution_handlers.at(ext).read_fun(resolvedPath.c_str(), /* req_size */asset.size(), asset.data(), &read_size, err, userdata);
if (ret != 0) {
return false;
}

if (read_size < sz) {
asset.resize(read_size);
// May optimize memory usage
asset.shrink_to_fit();
}

(*asset_out) = std::move(asset);

return true;
} else {
DCOUT("Resolve function is nullptr. Fallback to built-in file handler.");
}
}

std::vector<uint8_t> data;
size_t max_bytes = 1024 * 1024 * _max_asset_bytes_in_mb;
if (!io::ReadWholeFile(&data, err, resolvedPath, max_bytes,
/* userdata */ nullptr)) {
return false;
}

asset_out->set_data(std::move(data));

return true;
}

} // namespace tinyusdz
Loading

0 comments on commit 70ffec0

Please sign in to comment.