psemek/libs/android/source/resource.cpp

59 lines
1.2 KiB
C++

#include <psemek/app/resource.hpp>
#include <psemek/log/log.hpp>
#include <psemek/util/to_string.hpp>
#include <android/asset_manager_jni.h>
namespace
{
jobject assetManagerRef;
AAssetManager * assetManager;
struct stream_impl
: psemek::io::istream
{
stream_impl(AAsset * asset)
: asset_(asset)
{}
~stream_impl()
{
AAsset_close(asset_);
}
std::size_t read(char * p, std::size_t size) override
{
int result = AAsset_read(asset_, p, size);
if (result < 0)
throw std::runtime_error("Failed to read from resource");
return result;
}
private:
AAsset * asset_;
};
}
namespace psemek::app
{
std::unique_ptr<io::istream> open_resource(std::filesystem::path const & relative_path)
{
log::error() << "Opening resource " << relative_path;
auto asset = AAssetManager_open(assetManager, relative_path.c_str(), AASSET_MODE_STREAMING);
if (!asset)
throw std::runtime_error(util::to_string("Failed to open resource ", relative_path));
return std::make_unique<stream_impl>(asset);
}
}
extern "C" void Java_psemek_app_PsemekApplication_setAssetManager(JNIEnv * env, jclass, jobject manager)
{
assetManagerRef = env->NewLocalRef(manager);
assetManager = AAssetManager_fromJava(env, manager);
}