64 lines
1.3 KiB
C++
64 lines
1.3 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;
|
|
}
|
|
|
|
bool finished() const override
|
|
{
|
|
return AAsset_getRemainingLength64(asset_) == 0;
|
|
}
|
|
|
|
private:
|
|
AAsset * asset_;
|
|
};
|
|
|
|
}
|
|
|
|
namespace psemek::app
|
|
{
|
|
|
|
std::unique_ptr<io::istream> open_resource(std::filesystem::path const & relative_path)
|
|
{
|
|
log::info() << "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);
|
|
}
|