mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-27 15:25:38 +03:00
Make Logger
class static and introduce LoggerContext
A thread local LoggerContext is now used to hold the output file stream instead of the `Logger` class. Before doing any logging operations, a LoggerContext must be initialized. This commit will not build successfully on purpose.
This commit is contained in:
parent
69ef93bfa8
commit
769e6c933d
@ -106,6 +106,7 @@ add_library(skyline SHARED
|
||||
${source_DIR}/emu_jni.cpp
|
||||
${source_DIR}/loader_jni.cpp
|
||||
${source_DIR}/skyline/common.cpp
|
||||
${source_DIR}/skyline/common/logger.cpp
|
||||
${source_DIR}/skyline/common/settings.cpp
|
||||
${source_DIR}/skyline/common/signal.cpp
|
||||
${source_DIR}/skyline/common/uuid.cpp
|
||||
|
@ -4,10 +4,10 @@
|
||||
#include <csignal>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <android/log.h>
|
||||
#include <android/asset_manager_jni.h>
|
||||
#include <sys/system_properties.h>
|
||||
#include "skyline/common.h"
|
||||
#include "skyline/common/logger.h"
|
||||
#include "skyline/common/language.h"
|
||||
#include "skyline/common/signal.h"
|
||||
#include "skyline/common/settings.h"
|
||||
@ -55,6 +55,17 @@ static std::string GetTimeZoneName() {
|
||||
return "GMT";
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void Java_emu_skyline_SkylineApplication_initializeLog(
|
||||
JNIEnv *env,
|
||||
jobject,
|
||||
jstring appFilesPathJstring,
|
||||
jint logLevel
|
||||
) {
|
||||
std::string appFilesPath{env->GetStringUTFChars(appFilesPathJstring, nullptr)};
|
||||
skyline::Logger::configLevel = static_cast<skyline::Logger::LogLevel>(logLevel);
|
||||
skyline::Logger::LoaderContext.Initialize(appFilesPath + "loader.log");
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void Java_emu_skyline_EmulationActivity_executeApplication(
|
||||
JNIEnv *env,
|
||||
jobject instance,
|
||||
@ -77,7 +88,7 @@ extern "C" JNIEXPORT void Java_emu_skyline_EmulationActivity_executeApplication(
|
||||
close(preferenceFd);
|
||||
|
||||
skyline::JniString appFilesPath(env, appFilesPathJstring);
|
||||
auto logger{std::make_shared<skyline::Logger>(appFilesPath + "skyline.log", settings->logLevel)};
|
||||
skyline::Logger::EmulationContext.Initialize(appFilesPath + "emulation.log");
|
||||
|
||||
auto start{std::chrono::steady_clock::now()};
|
||||
|
||||
@ -90,7 +101,6 @@ extern "C" JNIEXPORT void Java_emu_skyline_EmulationActivity_executeApplication(
|
||||
try {
|
||||
auto os{std::make_shared<skyline::kernel::OS>(
|
||||
jvmManager,
|
||||
logger,
|
||||
settings,
|
||||
appFilesPath,
|
||||
GetTimeZoneName(),
|
||||
@ -121,6 +131,7 @@ extern "C" JNIEXPORT void Java_emu_skyline_EmulationActivity_executeApplication(
|
||||
auto end{std::chrono::steady_clock::now()};
|
||||
logger->Write(skyline::Logger::LogLevel::Info, fmt::format("Emulation has ended in {}ms", std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count()));
|
||||
|
||||
skyline::Logger::EmulationContext.Finalize();
|
||||
close(romFd);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||
|
||||
#include "skyline/common/logger.h"
|
||||
#include "skyline/crypto/key_store.h"
|
||||
#include "skyline/vfs/nca.h"
|
||||
#include "skyline/vfs/os_backing.h"
|
||||
@ -14,6 +15,8 @@
|
||||
extern "C" JNIEXPORT jint JNICALL Java_emu_skyline_loader_RomFile_populate(JNIEnv *env, jobject thiz, jint jformat, jint fd, jstring appFilesPathJstring, jint systemLanguage) {
|
||||
skyline::loader::RomFormat format{static_cast<skyline::loader::RomFormat>(jformat)};
|
||||
|
||||
skyline::Logger::SetContext(&skyline::Logger::LoaderContext);
|
||||
|
||||
auto keyStore{std::make_shared<skyline::crypto::KeyStore>(skyline::JniString(env, appFilesPathJstring))};
|
||||
std::unique_ptr<skyline::loader::Loader> loader;
|
||||
try {
|
||||
|
@ -1,7 +1,6 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||
|
||||
#include <android/log.h>
|
||||
#include "common.h"
|
||||
#include "nce.h"
|
||||
#include "soc.h"
|
||||
@ -11,45 +10,8 @@
|
||||
#include "kernel/types/KProcess.h"
|
||||
|
||||
namespace skyline {
|
||||
Logger::Logger(const std::string &path, LogLevel configLevel)
|
||||
: configLevel(configLevel),
|
||||
start(util::GetTimeNs() / constant::NsInMillisecond) {
|
||||
logFile.open(path, std::ios::trunc);
|
||||
UpdateTag();
|
||||
Write(LogLevel::Info, "Logging started");
|
||||
}
|
||||
|
||||
Logger::~Logger() {
|
||||
Write(LogLevel::Info, "Logging ended");
|
||||
logFile.flush();
|
||||
}
|
||||
|
||||
thread_local static std::string logTag, threadName;
|
||||
|
||||
void Logger::UpdateTag() {
|
||||
std::array<char, 16> name;
|
||||
if (!pthread_getname_np(pthread_self(), name.data(), name.size()))
|
||||
threadName = name.data();
|
||||
else
|
||||
threadName = "unk";
|
||||
logTag = std::string("emu-cpp-") + threadName;
|
||||
}
|
||||
|
||||
void Logger::Write(LogLevel level, const std::string &str) {
|
||||
constexpr std::array<char, 5> levelCharacter{'E', 'W', 'I', 'D', 'V'}; // The LogLevel as written out to a file
|
||||
constexpr std::array<int, 5> levelAlog{ANDROID_LOG_ERROR, ANDROID_LOG_WARN, ANDROID_LOG_INFO, ANDROID_LOG_DEBUG, ANDROID_LOG_VERBOSE}; // This corresponds to LogLevel and provides its equivalent for NDK Logging
|
||||
|
||||
if (logTag.empty())
|
||||
UpdateTag();
|
||||
|
||||
__android_log_write(levelAlog[static_cast<u8>(level)], logTag.c_str(), str.c_str());
|
||||
|
||||
std::lock_guard guard(mutex);
|
||||
logFile << '\036' << levelCharacter[static_cast<u8>(level)] << '\035' << std::dec << (util::GetTimeNs() / constant::NsInMillisecond) - start << '\035' << threadName << '\035' << str << '\n'; // We use RS (\036) and GS (\035) as our delimiters
|
||||
}
|
||||
|
||||
DeviceState::DeviceState(kernel::OS *os, std::shared_ptr<JvmManager> jvmManager, std::shared_ptr<Settings> settings, std::shared_ptr<Logger> logger)
|
||||
: os(os), jvm(std::move(jvmManager)), settings(std::move(settings)), logger(std::move(logger)) {
|
||||
DeviceState::DeviceState(kernel::OS *os, std::shared_ptr<JvmManager> jvmManager, std::shared_ptr<Settings> settings)
|
||||
: os(os), jvm(std::move(jvmManager)), settings(std::move(settings)) {
|
||||
// We assign these later as they use the state in their constructor and we don't want null pointers
|
||||
gpu = std::make_shared<gpu::GPU>(*this);
|
||||
soc = std::make_shared<soc::SOC>(*this);
|
||||
|
@ -8,7 +8,6 @@
|
||||
#include <unordered_map>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <mutex>
|
||||
#include <shared_mutex>
|
||||
#include <functional>
|
||||
@ -21,152 +20,6 @@
|
||||
#include <common/result.h>
|
||||
|
||||
namespace skyline {
|
||||
/**
|
||||
* @brief A wrapper around writing logs into a log file and logcat using Android Log APIs
|
||||
*/
|
||||
class Logger {
|
||||
private:
|
||||
std::mutex mutex; //!< Synchronizes all output I/O to ensure there are no races
|
||||
std::ofstream logFile; //!< An output stream to the log file
|
||||
i64 start; //!< A timestamp in milliseconds for when the logger was started, this is used as the base for all log timestamps
|
||||
|
||||
public:
|
||||
enum class LogLevel {
|
||||
Error,
|
||||
Warn,
|
||||
Info,
|
||||
Debug,
|
||||
Verbose,
|
||||
};
|
||||
|
||||
LogLevel configLevel; //!< The minimum level of logs to write
|
||||
|
||||
/**
|
||||
* @param path The path of the log file
|
||||
* @param configLevel The minimum level of logs to write
|
||||
*/
|
||||
Logger(const std::string &path, LogLevel configLevel);
|
||||
|
||||
/**
|
||||
* @brief Writes the termination message to the log file
|
||||
*/
|
||||
~Logger();
|
||||
|
||||
/**
|
||||
* @brief Update the tag in log messages with a new thread name
|
||||
*/
|
||||
static void UpdateTag();
|
||||
|
||||
void Write(LogLevel level, const std::string &str);
|
||||
|
||||
/**
|
||||
* @brief A wrapper around a string which captures the calling function using Clang source location builtins
|
||||
* @note A function needs to be declared for every argument template specialization as CTAD cannot work with implicit casting
|
||||
* @url https://clang.llvm.org/docs/LanguageExtensions.html#source-location-builtins
|
||||
*/
|
||||
template<typename S>
|
||||
struct FunctionString {
|
||||
S string;
|
||||
const char *function;
|
||||
|
||||
constexpr FunctionString(S string, const char *function = __builtin_FUNCTION()) : string(std::move(string)), function(function) {}
|
||||
|
||||
std::string operator*() {
|
||||
return std::string(function) + ": " + std::string(string);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename... Args>
|
||||
void Error(FunctionString<const char*> formatString, Args &&... args) {
|
||||
if (LogLevel::Error <= configLevel)
|
||||
Write(LogLevel::Error, util::Format(*formatString, args...));
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void Error(FunctionString<std::string> formatString, Args &&... args) {
|
||||
if (LogLevel::Error <= configLevel)
|
||||
Write(LogLevel::Error, util::Format(*formatString, args...));
|
||||
}
|
||||
|
||||
template<typename S, typename... Args>
|
||||
void ErrorNoPrefix(S formatString, Args &&... args) {
|
||||
if (LogLevel::Error <= configLevel)
|
||||
Write(LogLevel::Error, util::Format(formatString, args...));
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void Warn(FunctionString<const char*> formatString, Args &&... args) {
|
||||
if (LogLevel::Warn <= configLevel)
|
||||
Write(LogLevel::Warn, util::Format(*formatString, args...));
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void Warn(FunctionString<std::string> formatString, Args &&... args) {
|
||||
if (LogLevel::Warn <= configLevel)
|
||||
Write(LogLevel::Warn, util::Format(*formatString, args...));
|
||||
}
|
||||
|
||||
template<typename S, typename... Args>
|
||||
void WarnNoPrefix(S formatString, Args &&... args) {
|
||||
if (LogLevel::Warn <= configLevel)
|
||||
Write(LogLevel::Warn, util::Format(formatString, args...));
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void Info(FunctionString<const char*> formatString, Args &&... args) {
|
||||
if (LogLevel::Info <= configLevel)
|
||||
Write(LogLevel::Info, util::Format(*formatString, args...));
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void Info(FunctionString<std::string> formatString, Args &&... args) {
|
||||
if (LogLevel::Info <= configLevel)
|
||||
Write(LogLevel::Info, util::Format(*formatString, args...));
|
||||
}
|
||||
|
||||
template<typename S, typename... Args>
|
||||
void InfoNoPrefix(S formatString, Args &&... args) {
|
||||
if (LogLevel::Info <= configLevel)
|
||||
Write(LogLevel::Info, util::Format(formatString, args...));
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void Debug(FunctionString<const char*> formatString, Args &&... args) {
|
||||
if (LogLevel::Debug <= configLevel)
|
||||
Write(LogLevel::Debug, util::Format(*formatString, args...));
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void Debug(FunctionString<std::string> formatString, Args &&... args) {
|
||||
if (LogLevel::Debug <= configLevel)
|
||||
Write(LogLevel::Debug, util::Format(*formatString, args...));
|
||||
}
|
||||
|
||||
template<typename S, typename... Args>
|
||||
void DebugNoPrefix(S formatString, Args &&... args) {
|
||||
if (LogLevel::Debug <= configLevel)
|
||||
Write(LogLevel::Debug, util::Format(formatString, args...));
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void Verbose(FunctionString<const char*> formatString, Args &&... args) {
|
||||
if (LogLevel::Verbose <= configLevel)
|
||||
Write(LogLevel::Verbose, util::Format(*formatString, args...));
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void Verbose(FunctionString<std::string> formatString, Args &&... args) {
|
||||
if (LogLevel::Verbose <= configLevel)
|
||||
Write(LogLevel::Verbose, util::Format(*formatString, args...));
|
||||
}
|
||||
|
||||
template<typename S, typename... Args>
|
||||
void VerboseNoPrefix(S formatString, Args &&... args) {
|
||||
if (LogLevel::Verbose <= configLevel)
|
||||
Write(LogLevel::Verbose, util::Format(formatString, args...));
|
||||
}
|
||||
};
|
||||
|
||||
class Settings;
|
||||
namespace nce {
|
||||
class NCE;
|
||||
@ -201,14 +54,13 @@ namespace skyline {
|
||||
* @brief The state of the entire emulator is contained within this class, all objects related to emulation are tied into it
|
||||
*/
|
||||
struct DeviceState {
|
||||
DeviceState(kernel::OS *os, std::shared_ptr<JvmManager> jvmManager, std::shared_ptr<Settings> settings, std::shared_ptr<Logger> logger);
|
||||
DeviceState(kernel::OS *os, std::shared_ptr<JvmManager> jvmManager, std::shared_ptr<Settings> settings);
|
||||
|
||||
~DeviceState();
|
||||
|
||||
kernel::OS *os;
|
||||
std::shared_ptr<JvmManager> jvm;
|
||||
std::shared_ptr<Settings> settings;
|
||||
std::shared_ptr<Logger> logger;
|
||||
std::shared_ptr<loader::Loader> loader;
|
||||
std::shared_ptr<kernel::type::KProcess> process{};
|
||||
static thread_local inline std::shared_ptr<kernel::type::KThread> thread{}; //!< The KThread of the thread which accesses this object
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <cstdint>
|
||||
#include <stdexcept>
|
||||
#include <variant>
|
||||
#include <bitset>
|
||||
#include <fmt/format.h>
|
||||
|
||||
namespace fmt {
|
||||
|
62
app/src/main/cpp/skyline/common/logger.cpp
Normal file
62
app/src/main/cpp/skyline/common/logger.cpp
Normal file
@ -0,0 +1,62 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
// Copyright © 2021 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||
|
||||
#include <android/log.h>
|
||||
#include "logger.h"
|
||||
|
||||
namespace skyline {
|
||||
void Logger::LoggerContext::Initialize(const std::string &path) {
|
||||
start = util::GetTimeNs() / constant::NsInMillisecond;
|
||||
logFile.open(path, std::ios::trunc);
|
||||
}
|
||||
|
||||
void Logger::LoggerContext::Finalize() {
|
||||
logFile.close();
|
||||
}
|
||||
|
||||
void Logger::LoggerContext::Flush() {
|
||||
logFile.flush();
|
||||
}
|
||||
|
||||
thread_local static std::string logTag, threadName;
|
||||
thread_local static Logger::LoggerContext *context{&Logger::EmulationContext};
|
||||
|
||||
void Logger::UpdateTag() {
|
||||
std::array<char, 16> name;
|
||||
if (!pthread_getname_np(pthread_self(), name.data(), name.size()))
|
||||
threadName = name.data();
|
||||
else
|
||||
threadName = "unk";
|
||||
logTag = std::string("emu-cpp-") + threadName;
|
||||
}
|
||||
|
||||
Logger::LoggerContext *Logger::GetContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
void Logger::SetContext(LoggerContext *pContext) {
|
||||
context = pContext;
|
||||
}
|
||||
|
||||
void Logger::WriteAndroid(LogLevel level, const std::string &str) {
|
||||
constexpr std::array<int, 5> levelAlog{ANDROID_LOG_ERROR, ANDROID_LOG_WARN, ANDROID_LOG_INFO, ANDROID_LOG_DEBUG, ANDROID_LOG_VERBOSE}; // This corresponds to LogLevel and provides its equivalent for NDK Logging
|
||||
if (logTag.empty())
|
||||
UpdateTag();
|
||||
|
||||
__android_log_write(levelAlog[static_cast<u8>(level)], logTag.c_str(), str.c_str());
|
||||
}
|
||||
|
||||
void Logger::Write(LogLevel level, const std::string &str) {
|
||||
constexpr std::array<char, 5> levelCharacter{'E', 'W', 'I', 'D', 'V'}; // The LogLevel as written out to a file
|
||||
WriteAndroid(level, str);
|
||||
|
||||
if (context)
|
||||
// We use RS (\036) and GS (\035) as our delimiters
|
||||
context->Write(fmt::format("\036{}\035{}\035{}\035{}\n", levelCharacter[static_cast<u8>(level)], (util::GetTimeNs() / constant::NsInMillisecond) - context->start, threadName, str));
|
||||
}
|
||||
|
||||
void Logger::LoggerContext::Write(const std::string &str) {
|
||||
std::lock_guard guard(mutex);
|
||||
logFile << str;
|
||||
}
|
||||
}
|
169
app/src/main/cpp/skyline/common/logger.h
Normal file
169
app/src/main/cpp/skyline/common/logger.h
Normal file
@ -0,0 +1,169 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
// Copyright © 2021 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <fstream>
|
||||
#include <mutex>
|
||||
#include "common.h"
|
||||
|
||||
namespace skyline {
|
||||
/**
|
||||
* @brief A wrapper around writing logs into a log file and logcat using Android Log APIs
|
||||
*/
|
||||
class Logger {
|
||||
private:
|
||||
Logger() {}
|
||||
|
||||
public:
|
||||
enum class LogLevel {
|
||||
Error,
|
||||
Warn,
|
||||
Info,
|
||||
Debug,
|
||||
Verbose,
|
||||
};
|
||||
|
||||
static inline LogLevel configLevel{LogLevel::Verbose}; //!< The minimum level of logs to write
|
||||
|
||||
/**
|
||||
* @brief Holds logger variables that cannot be static
|
||||
*/
|
||||
struct LoggerContext {
|
||||
std::mutex mutex; //!< Synchronizes all output I/O to ensure there are no races
|
||||
std::ofstream logFile; //!< An output stream to the log file
|
||||
i64 start; //!< A timestamp in milliseconds for when the logger was started, this is used as the base for all log timestamps
|
||||
|
||||
LoggerContext() {}
|
||||
|
||||
void Initialize(const std::string &path);
|
||||
|
||||
void Finalize();
|
||||
|
||||
void Flush();
|
||||
|
||||
void Write(const std::string &str);
|
||||
};
|
||||
static inline LoggerContext EmulationContext, LoaderContext;
|
||||
|
||||
/**
|
||||
* @brief Update the tag in log messages with a new thread name
|
||||
*/
|
||||
static void UpdateTag();
|
||||
|
||||
static LoggerContext *GetContext();
|
||||
|
||||
static void SetContext(LoggerContext *context);
|
||||
|
||||
static void WriteAndroid(LogLevel level, const std::string &str);
|
||||
|
||||
static void Write(LogLevel level, const std::string &str);
|
||||
|
||||
/**
|
||||
* @brief A wrapper around a string which captures the calling function using Clang source location builtins
|
||||
* @note A function needs to be declared for every argument template specialization as CTAD cannot work with implicit casting
|
||||
* @url https://clang.llvm.org/docs/LanguageExtensions.html#source-location-builtins
|
||||
*/
|
||||
template<typename S>
|
||||
struct FunctionString {
|
||||
S string;
|
||||
const char *function;
|
||||
|
||||
FunctionString(S string, const char *function = __builtin_FUNCTION()) : string(std::move(string)), function(function) {}
|
||||
|
||||
std::string operator*() {
|
||||
return std::string(function) + ": " + std::string(string);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename... Args>
|
||||
static void Error(FunctionString<const char *> formatString, Args &&... args) {
|
||||
if (LogLevel::Error <= configLevel)
|
||||
Write(LogLevel::Error, util::Format(*formatString, args...));
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
static void Error(FunctionString<std::string> formatString, Args &&... args) {
|
||||
if (LogLevel::Error <= configLevel)
|
||||
Write(LogLevel::Error, util::Format(*formatString, args...));
|
||||
}
|
||||
|
||||
template<typename S, typename... Args>
|
||||
static void ErrorNoPrefix(S formatString, Args &&... args) {
|
||||
if (LogLevel::Error <= configLevel)
|
||||
Write(LogLevel::Error, util::Format(formatString, args...));
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
static void Warn(FunctionString<const char *> formatString, Args &&... args) {
|
||||
if (LogLevel::Warn <= configLevel)
|
||||
Write(LogLevel::Warn, util::Format(*formatString, args...));
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
static void Warn(FunctionString<std::string> formatString, Args &&... args) {
|
||||
if (LogLevel::Warn <= configLevel)
|
||||
Write(LogLevel::Warn, util::Format(*formatString, args...));
|
||||
}
|
||||
|
||||
template<typename S, typename... Args>
|
||||
static void WarnNoPrefix(S formatString, Args &&... args) {
|
||||
if (LogLevel::Warn <= configLevel)
|
||||
Write(LogLevel::Warn, util::Format(formatString, args...));
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
static void Info(FunctionString<const char *> formatString, Args &&... args) {
|
||||
if (LogLevel::Info <= configLevel)
|
||||
Write(LogLevel::Info, util::Format(*formatString, args...));
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
static void Info(FunctionString<std::string> formatString, Args &&... args) {
|
||||
if (LogLevel::Info <= configLevel)
|
||||
Write(LogLevel::Info, util::Format(*formatString, args...));
|
||||
}
|
||||
|
||||
template<typename S, typename... Args>
|
||||
static void InfoNoPrefix(S formatString, Args &&... args) {
|
||||
if (LogLevel::Info <= configLevel)
|
||||
Write(LogLevel::Info, util::Format(formatString, args...));
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
static void Debug(FunctionString<const char *> formatString, Args &&... args) {
|
||||
if (LogLevel::Debug <= configLevel)
|
||||
Write(LogLevel::Debug, util::Format(*formatString, args...));
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
static void Debug(FunctionString<std::string> formatString, Args &&... args) {
|
||||
if (LogLevel::Debug <= configLevel)
|
||||
Write(LogLevel::Debug, util::Format(*formatString, args...));
|
||||
}
|
||||
|
||||
template<typename S, typename... Args>
|
||||
static void DebugNoPrefix(S formatString, Args &&... args) {
|
||||
if (LogLevel::Debug <= configLevel)
|
||||
Write(LogLevel::Debug, util::Format(formatString, args...));
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
static void Verbose(FunctionString<const char *> formatString, Args &&... args) {
|
||||
if (LogLevel::Verbose <= configLevel)
|
||||
Write(LogLevel::Verbose, util::Format(*formatString, args...));
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
static void Verbose(FunctionString<std::string> formatString, Args &&... args) {
|
||||
if (LogLevel::Verbose <= configLevel)
|
||||
Write(LogLevel::Verbose, util::Format(*formatString, args...));
|
||||
}
|
||||
|
||||
template<typename S, typename... Args>
|
||||
static void VerboseNoPrefix(S formatString, Args &&... args) {
|
||||
if (LogLevel::Verbose <= configLevel)
|
||||
Write(LogLevel::Verbose, util::Format(formatString, args...));
|
||||
}
|
||||
};
|
||||
}
|
@ -4,6 +4,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <random>
|
||||
#include <span>
|
||||
#include <frozen/unordered_map.h>
|
||||
#include <frozen/string.h>
|
||||
#include "base.h"
|
||||
|
@ -15,13 +15,12 @@
|
||||
namespace skyline::kernel {
|
||||
OS::OS(
|
||||
std::shared_ptr<JvmManager> &jvmManager,
|
||||
std::shared_ptr<Logger> &logger,
|
||||
std::shared_ptr<Settings> &settings,
|
||||
std::string appFilesPath,
|
||||
std::string deviceTimeZone,
|
||||
language::SystemLanguage systemLanguage,
|
||||
std::shared_ptr<vfs::FileSystem> assetFileSystem)
|
||||
: state(this, jvmManager, settings, logger),
|
||||
: state(this, jvmManager, settings),
|
||||
appFilesPath(std::move(appFilesPath)),
|
||||
deviceTimeZone(std::move(deviceTimeZone)),
|
||||
assetFileSystem(std::move(assetFileSystem)),
|
||||
|
@ -22,13 +22,11 @@ namespace skyline::kernel {
|
||||
language::SystemLanguage systemLanguage;
|
||||
|
||||
/**
|
||||
* @param logger An instance of the Logger class
|
||||
* @param settings An instance of the Settings class
|
||||
* @param window The ANativeWindow object to draw the screen to
|
||||
*/
|
||||
OS(
|
||||
std::shared_ptr<JvmManager> &jvmManager,
|
||||
std::shared_ptr<Logger> &logger,
|
||||
std::shared_ptr<Settings> &settings,
|
||||
std::string appFilesPath,
|
||||
std::string deviceTimeZone,
|
||||
|
@ -37,10 +37,6 @@ class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback, View.OnTo
|
||||
private var emulationThread : Thread? = null
|
||||
}
|
||||
|
||||
init {
|
||||
System.loadLibrary("skyline") // libskyline.so
|
||||
}
|
||||
|
||||
private val binding by lazy { EmuActivityBinding.inflate(layoutInflater) }
|
||||
|
||||
/**
|
||||
|
@ -7,6 +7,15 @@ package emu.skyline
|
||||
|
||||
import android.app.Application
|
||||
import dagger.hilt.android.HiltAndroidApp
|
||||
import emu.skyline.di.getSettings
|
||||
|
||||
@HiltAndroidApp
|
||||
class SkylineApplication : Application()
|
||||
class SkylineApplication : Application() {
|
||||
private external fun initializeLog(appFilesPath : String, logLevel : Int)
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
System.loadLibrary("skyline")
|
||||
initializeLog(applicationContext.filesDir.canonicalPath + "/", getSettings().logLevel.toInt())
|
||||
}
|
||||
}
|
||||
|
@ -127,8 +127,6 @@ internal class RomFile(context : Context, format : RomFormat, uri : Uri, systemL
|
||||
get() = result == LoaderResult.Success
|
||||
|
||||
init {
|
||||
System.loadLibrary("skyline")
|
||||
|
||||
context.contentResolver.openFileDescriptor(uri, "r")!!.use {
|
||||
result = LoaderResult.get(populate(format.ordinal, it.fd, context.filesDir.canonicalPath + "/", systemLanguage))
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user