Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f1793754c5 | ||
|
|
71a54ff4c5 | ||
|
|
5e9abf3c52 | ||
|
|
e1edfa5946 |
No files matched your search
@@ -2,6 +2,10 @@ cmake_minimum_required(VERSION 3.12)
|
||||
project(spark)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
|
||||
if(MY_TEST_VCPKG)
|
||||
add_subdirectory(src/lib_system)
|
||||
add_subdirectory(src/app_tester)
|
||||
else()
|
||||
if(WIN32)
|
||||
set(platform "windows")
|
||||
else()
|
||||
@@ -154,3 +158,4 @@ else()
|
||||
DESTINATION "${SPARK_INSTALL_PREFIX}/bin")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
@@ -34,6 +34,42 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "spark-clang",
|
||||
"binaryDir": "${sourceDir}/build/${presetName}",
|
||||
"generator": "'Ninja Multi-Config'",
|
||||
"cacheVariables": {
|
||||
"CMAKE_C_COMPILER": "clang",
|
||||
"CMAKE_CXX_COMPILER": "clang++",
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS": {
|
||||
"type": "BOOL",
|
||||
"value": "ON"
|
||||
},
|
||||
"CMAKE_CXX_STANDARD": "20",
|
||||
"CMAKE_TOOLCHAIN_FILE": "${sourceDir}/vcpkg/scripts/buildsystems/vcpkg.cmake",
|
||||
"EXTERNALS_ROOT": "${sourceDir}/externals/windows",
|
||||
"CONFIG_DEFAULTS_PATH": "config/profiles/default/*.conf",
|
||||
"DOTNET_BINARY_DIR": "${sourceDir}/build/$<CONFIG>/bin/net7.0",
|
||||
"DOTNET_WINDOWS_BINARY_DIR": "${sourceDir}/build/$<CONFIG>/bin/net7.0-windows"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "tester",
|
||||
"generator": "Visual Studio 17 2022",
|
||||
"binaryDir": "${sourceDir}/build/tester",
|
||||
"cacheVariables": {
|
||||
"CMAKE_CXX_STANDARD": "20",
|
||||
"CMAKE_SHARED_LINKER_FLAGS_DEBUG": "/DEBUG",
|
||||
"CMAKE_SHARED_LINKER_FLAGS_RELEASE": "/OPT:REF /OPT:ICF /LTCG",
|
||||
"CMAKE_TOOLCHAIN_FILE": "${sourceDir}/vcpkg/scripts/buildsystems/vcpkg.cmake",
|
||||
"MY_TEST_VCPKG": {
|
||||
"type": "BOOL",
|
||||
"value": "ON"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "sparkd",
|
||||
"condition": {
|
||||
@@ -258,6 +294,35 @@
|
||||
"configuration": "Release"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "spark-debug-clang",
|
||||
"displayName": "Debug (clang)",
|
||||
"inherits": "spark",
|
||||
"configurePreset": "spark-clang",
|
||||
"configuration": "Debug"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "spark-release-clang",
|
||||
"displayName": "Release (clang)",
|
||||
"inherits": "spark",
|
||||
"configurePreset": "spark-clang",
|
||||
"configuration": "Release"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "tester",
|
||||
"hidden": true
|
||||
},
|
||||
|
||||
{
|
||||
"name": "tester-debug",
|
||||
"displayName": "Debug",
|
||||
"inherits": "tester",
|
||||
"configurePreset": "tester",
|
||||
"configuration": "Debug"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "sparkd",
|
||||
"condition": {
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
function(init_executable source_dir)
|
||||
file(
|
||||
GLOB_RECURSE ${PROJECT_NAME}_Sources
|
||||
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${source_dir}/*.cpp)
|
||||
add_executable(${PROJECT_NAME} ${${PROJECT_NAME}_Sources})
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
endfunction(init_executable)
|
||||
@@ -0,0 +1,29 @@
|
||||
function(init_library source_dir)
|
||||
file(
|
||||
GLOB_RECURSE ${PROJECT_NAME}_Sources
|
||||
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${source_dir}/*.cpp)
|
||||
|
||||
# Note: cpp files inside 'tests' dir(s) are considered tests.
|
||||
# Remove tests from main sources, and add them to test sources
|
||||
set(${PROJECT_NAME}_Test_Sources)
|
||||
foreach(item ${${PROJECT_NAME}_Sources})
|
||||
if(${item} MATCHES "tests/*.cpp")
|
||||
list(REMOVE_ITEM ${PROJECT_NAME}_Sources ${item})
|
||||
list(APPEND ${PROJECT_NAME}_Test_Sources ${item})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# Add main library
|
||||
add_library(${PROJECT_NAME} ${${PROJECT_NAME}_Sources})
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
# Add tests executable (if there are any)
|
||||
if (${PROJECT_NAME}_Test_Sources)
|
||||
add_executable(${PROJECT_NAME}-tests ${${PROJECT_NAME}_Test_Sources})
|
||||
target_link_libraries(${PROJECT_NAME}-tests PRIVATE ${PROJECT_NAME})
|
||||
# Catch2
|
||||
find_package(Catch2 CONFIG REQUIRED COMPONENTS Catch2WithMain)
|
||||
target_link_libraries(${PROJECT_NAME}-tests PRIVATE Catch2::Catch2WithMain)
|
||||
endif()
|
||||
endfunction(init_library)
|
||||
@@ -8,6 +8,6 @@ namespace BCG
|
||||
|
||||
public class AddColumnsStream : MapStream
|
||||
{
|
||||
public AddColumnsStream(ViewStream vs, string columnDef) : base (vs, new ColumnAdder (columnDef)) {}
|
||||
public AddColumnsStream(ViewStream vs, string columnDef) : base (vs, default) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -104,13 +104,14 @@ namespace BCG {
|
||||
if (!p.replayed)
|
||||
return p;
|
||||
}
|
||||
else
|
||||
{
|
||||
double secondsElapsed = new BinaryReader(myFileReader).ReadDouble();
|
||||
myNextPacketTime = myPlaybackStart + new TimeSpan(0, 0, 0, 0, (int)(1000 * secondsElapsed / myPlaybackSpeed));
|
||||
if (onProgress != null)
|
||||
onProgress(myFileReader.Position, myFileReader.Length);
|
||||
}
|
||||
return default;
|
||||
// else
|
||||
// {
|
||||
// double secondsElapsed = new BinaryReader(myFileReader).ReadDouble();
|
||||
// myNextPacketTime = myPlaybackStart + new TimeSpan(0, 0, 0, 0, (int)(1000 * secondsElapsed / myPlaybackSpeed));
|
||||
// if (onProgress != null)
|
||||
// onProgress(myFileReader.Position, myFileReader.Length);
|
||||
// }
|
||||
}
|
||||
|
||||
#region IWorker Members
|
||||
@@ -130,7 +131,8 @@ namespace BCG {
|
||||
_fire_packet(ops, row_array);
|
||||
curr_packet.replay_timestamp = PersistorStream.epoch_now();
|
||||
} else {
|
||||
PlaybackPacket prev_packet = _get_previous_packet(curr_packet);
|
||||
PlaybackPacket prev_packet = new(0, 0, Array.Empty<byte>());
|
||||
// PlaybackPacket prev_packet = _get_previous_packet(curr_packet);
|
||||
// this is the time we need to fire (replay) this packet
|
||||
long time_to_fire = prev_packet.replay_timestamp + curr_packet.offset_from_previous;
|
||||
long now_epoch = PersistorStream.epoch_now();
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.23)
|
||||
project(bts-tester)
|
||||
include(${CMAKE_SOURCE_DIR}/cmake/InitExecutable.cmake)
|
||||
init_executable(tester)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC
|
||||
bts-system)
|
||||
@@ -0,0 +1,9 @@
|
||||
#include "system/foo.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
int main(int argc, char ** argv) {
|
||||
bts::system::Foo f{"jules"};
|
||||
f.say_hello();
|
||||
return 0;
|
||||
}
|
||||
@@ -84,7 +84,12 @@ namespace mbts.ui.shell {
|
||||
|
||||
base.OnStartup(e);
|
||||
_runtime = new ShellBootstrapper(
|
||||
_opts?.user, _opts?.password, _opts?.sparkd, _opts?.restore_workspace);
|
||||
_opts?.user,
|
||||
_opts?.password,
|
||||
_opts?.sparkd,
|
||||
_opts?.restore_workspace,
|
||||
_opts.verbose ? LogLevel.Diag : LogLevel.Warn,
|
||||
_opts.verbose ? LogLevel.Diag : LogLevel.Info);
|
||||
_runtime.Run();
|
||||
|
||||
// Select text on tab in
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
namespace mbts.ui.shell {
|
||||
using bts;
|
||||
|
||||
using mbts.config;
|
||||
using mbts.ui.extensions;
|
||||
|
||||
@@ -23,10 +25,13 @@
|
||||
string user = null,
|
||||
string password = null,
|
||||
string config_source = null,
|
||||
bool? restore_workspace = null
|
||||
bool? restore_workspace = null,
|
||||
LogLevel config_console_log_level = LogLevel.Warn,
|
||||
LogLevel config_file_log_level = LogLevel.Info
|
||||
) : base(config_source) {
|
||||
// Get the LoginModel instance on this thread to make sure it performs syncronous config initialization.
|
||||
var login_model = LoginModel.init(config_source);
|
||||
var login_model = LoginModel.init(
|
||||
config_source, config_console_log_level, config_file_log_level);
|
||||
// Show the dialog on a background thread so animations aren't blocked during the main application startup
|
||||
var thread = new Thread(thread_start) {
|
||||
IsBackground = true,
|
||||
|
||||
@@ -42,6 +42,11 @@ namespace Spark.Cli {
|
||||
[Option(_SPARKD_OPT_NAME, MetaValue = "URL", HelpText = "The config server url")]
|
||||
public string? sparkd { get; set; }
|
||||
|
||||
[Option(
|
||||
"verbose",
|
||||
HelpText ="Verbose logging while initializing config (once initialized, the log levels in config are used)")]
|
||||
public bool verbose { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Conform opts to modern cli for backwards compatibility
|
||||
/// </summary>
|
||||
|
||||
@@ -62,14 +62,19 @@ namespace mbts.ui.shell {
|
||||
static Lazy<LoginModel> _instance;
|
||||
|
||||
readonly string _config_source;
|
||||
readonly LogLevel _config_console_log_level;
|
||||
readonly LogLevel _config_file_log_level;
|
||||
private string _workspace;
|
||||
private PreloginWorkspaceEnumerator _enum_workspace;
|
||||
|
||||
ServiceContext _ctx;
|
||||
DispatcherFrame _frame = new DispatcherFrame();
|
||||
|
||||
LoginModel(string config_source) {
|
||||
LoginModel(
|
||||
string config_source, LogLevel config_console_log_level, LogLevel config_file_log_level) {
|
||||
_config_source = config_source;
|
||||
_config_console_log_level = config_console_log_level;
|
||||
_config_file_log_level = config_file_log_level;
|
||||
init().ignore();
|
||||
}
|
||||
|
||||
@@ -84,10 +89,12 @@ namespace mbts.ui.shell {
|
||||
public bool HasFatalError { get; set; }
|
||||
public User[] Users { get; private set; }
|
||||
|
||||
public static LoginModel init(string config_source) {
|
||||
public static LoginModel init(
|
||||
string config_source, LogLevel config_console_log_level, LogLevel config_file_log_level) {
|
||||
// '_instance' is lazy to guarentee it is only instantiated once
|
||||
Interlocked.CompareExchange(
|
||||
ref _instance, new(() => new(config_source)), null);
|
||||
ref _instance,
|
||||
new(() => new(config_source, config_console_log_level, config_file_log_level)), null);
|
||||
return _instance.Value;
|
||||
}
|
||||
|
||||
@@ -119,7 +126,7 @@ namespace mbts.ui.shell {
|
||||
public async Task<bool> init() {
|
||||
// Make sure config is initialized and working
|
||||
try {
|
||||
Configuration.initialize(_config_source);
|
||||
Configuration.initialize(_config_source, _config_console_log_level, _config_file_log_level);
|
||||
} catch (ApplicationException e) {
|
||||
ErrorMessage = (e.Message ?? string.Empty) + " " + (App.stunnel_job_error ?? string.Empty);
|
||||
HasFatalError = true;
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace bts.api.core {
|
||||
|
||||
public static ServiceContext create(string? config_server = null) {
|
||||
var args = Environment.GetCommandLineArgs();
|
||||
BTS.init(config_server, args);
|
||||
BTS.init(config_server, LogLevel.Warn, LogLevel.Info, args);
|
||||
var qbus = ApiNativeMethods.api_create_quickbus(null, 0);
|
||||
return new ServiceContext(qbus);
|
||||
}
|
||||
|
||||
@@ -50,14 +50,18 @@ namespace mbts.config {
|
||||
}
|
||||
}
|
||||
|
||||
public static void initialize(string? config_source = null) {
|
||||
public static void initialize(
|
||||
string? config_source = null,
|
||||
LogLevel config_console_log_level = LogLevel.Warn,
|
||||
LogLevel config_file_log_level = LogLevel.Info) {
|
||||
if (_state == State.OK) {
|
||||
return;
|
||||
}
|
||||
var cli_args = Environment.GetCommandLineArgs();
|
||||
// Considered doing this async on a background thread but it wouldn't do any good. The next
|
||||
// guy down the line to ask for config will just block until this completes.
|
||||
try {
|
||||
BTS.init(config_source);
|
||||
BTS.init(config_source, config_file_log_level, config_console_log_level, cli_args);
|
||||
} catch (ApplicationException) {
|
||||
_state = State.Error;
|
||||
throw;
|
||||
|
||||
@@ -9,17 +9,20 @@ namespace bts
|
||||
{
|
||||
static int _needs_init_spark_lib = 0;
|
||||
|
||||
public static void init(string config_source = null) {
|
||||
var args = Environment.GetCommandLineArgs();
|
||||
init(config_source, args);
|
||||
}
|
||||
|
||||
public static void init(string config_source = null, params string[] args) {
|
||||
public static void init(
|
||||
string config_source = null,
|
||||
LogLevel console_log_level = LogLevel.Warn,
|
||||
LogLevel file_log_level = LogLevel.Info,
|
||||
params string[] args) {
|
||||
utils.BTSNativeMethods.provide_command_line(args, args.Length);
|
||||
|
||||
var buffer = new StringBuilder(4096);
|
||||
bool config_ok = utils.BTSNativeMethods.initialize_nothrow(
|
||||
config_source ?? string.Empty, buffer, buffer.Capacity);
|
||||
config_source ?? string.Empty,
|
||||
buffer,
|
||||
buffer.Capacity,
|
||||
(short)console_log_level,
|
||||
(short)file_log_level);
|
||||
if (!config_ok) {
|
||||
throw new ApplicationException(buffer.ToString());
|
||||
}
|
||||
|
||||
@@ -27,6 +27,10 @@ namespace bts.utils
|
||||
|
||||
[DllImport("libspark")]
|
||||
public static extern bool initialize_nothrow(
|
||||
string config_source, StringBuilder buffer, int length);
|
||||
string config_source,
|
||||
StringBuilder buffer,
|
||||
int length,
|
||||
short console_log_level,
|
||||
short file_log_level);
|
||||
}
|
||||
}
|
||||
@@ -37,7 +37,7 @@ CAPI Quickbus *api_create_quickbus(const char *qbconfig, long length) {
|
||||
// If config hasn't been initialized yet do it now and suppress exceptions.
|
||||
// When we're called from a nuget package we may not have defaults which can
|
||||
// cause errors
|
||||
config::initialize_nothrow("", nullptr, 0);
|
||||
config::initialize_nothrow("", nullptr, 0, bts::Warn.ordinal, bts::Info.ordinal);
|
||||
|
||||
config::QuickbusNodeCfg cfg;
|
||||
if (length > 0 && qbconfig != nullptr &&
|
||||
|
||||
@@ -2,7 +2,7 @@ function(get_link_libraries dest)
|
||||
find_package(fmt CONFIG REQUIRED)
|
||||
set(${dest}
|
||||
crypt32
|
||||
fmt::fmt
|
||||
fmt::fmt-header-only
|
||||
libcrypto
|
||||
libcurl
|
||||
libboost_system
|
||||
|
||||
@@ -15,7 +15,9 @@ namespace internal {
|
||||
// To allow config diagnostic logging
|
||||
class ConfigLog {
|
||||
public:
|
||||
ConfigLog();
|
||||
explicit ConfigLog(
|
||||
bts::log::Level console_log_level = bts::Warn,
|
||||
bts::log::Level file_log_level = bts::Info);
|
||||
~ConfigLog();
|
||||
|
||||
void info(const std::string &msg);
|
||||
@@ -50,7 +52,7 @@ class ConfigLog {
|
||||
// Definition
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
inline ConfigLog::ConfigLog()
|
||||
inline ConfigLog::ConfigLog(bts::log::Level console_log_level, bts::log::Level file_log_level)
|
||||
: print_errors_(true), logger_hub_("config_logger"),
|
||||
logger_(logger_hub_.make_logger()) {
|
||||
log::LoggingConfig cfg;
|
||||
@@ -66,9 +68,9 @@ inline ConfigLog::ConfigLog()
|
||||
}
|
||||
|
||||
cfg.deployment_type = "Config";
|
||||
f[log::Cfg.ordinal] = Warn;
|
||||
f[log::Cfg.ordinal] = console_log_level;
|
||||
cfg.sinks["console"] = std::make_pair(log::console_sink(cfg), f);
|
||||
f[log::Cfg.ordinal] = Info;
|
||||
f[log::Cfg.ordinal] = file_log_level;
|
||||
cfg.sinks["syslog"] = std::make_pair(log::syslog_sink(cfg), f);
|
||||
logger_hub_.config(cfg);
|
||||
|
||||
@@ -126,7 +128,7 @@ inline bool ConfigLog::enqueue(
|
||||
return false;
|
||||
}
|
||||
return logger_.enqueue(
|
||||
log::log_ts(), log::Cfg, level, file, line, msg_template, msg_args...);
|
||||
log::log_ts(), log::Cfg, level, file, line, msg_template, std::move(msg_args)...);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
@@ -97,7 +97,8 @@ void run_config_query(
|
||||
void ConfigQuerier::init_(bool verbose) {
|
||||
char buffer[4096] = {0};
|
||||
utils::TimeStamp start = utils::TimeStamp::now();
|
||||
bool success = config::initialize_nothrow("", buffer, sizeof(buffer));
|
||||
bool success = config::initialize_nothrow(
|
||||
"", buffer, sizeof(buffer), bts::Warn.ordinal, bts::Info.ordinal);
|
||||
double time = (utils::TimeStamp::now() - start).seconds();
|
||||
|
||||
if (success) {
|
||||
|
||||
@@ -362,7 +362,7 @@ void check_rule(
|
||||
}
|
||||
|
||||
void ConfigurationState::check_rules() {
|
||||
initialize("");
|
||||
initialize("", bts::Warn.ordinal, bts::Info.ordinal);
|
||||
std::vector<std::shared_ptr<proto::Message>>::iterator iter;
|
||||
for (iter = _config_chain.begin(); iter != _config_chain.end(); ++iter) {
|
||||
proto::Message *message = (*iter).get();
|
||||
@@ -371,12 +371,13 @@ void ConfigurationState::check_rules() {
|
||||
check_rule(_defaults.get(), _rule_engine);
|
||||
}
|
||||
|
||||
void ConfigurationState::initialize_settings(string config_source) {
|
||||
void ConfigurationState::initialize_settings(
|
||||
string config_source, bts::log::Level console_log_level, bts::log::Level file_log_level) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_initialization_mutex);
|
||||
if (_is_initialized)
|
||||
return;
|
||||
|
||||
ConfigLog log;
|
||||
ConfigLog log{console_log_level, file_log_level};
|
||||
CFG_LOG(log, Info, "Initializing settings from '{}'", config_source);
|
||||
// For verbose config logs, uncomment line below
|
||||
// log.set_print_errors(true);
|
||||
|
||||
@@ -60,7 +60,10 @@ class ConfigurationState {
|
||||
* @param config_source The source from which to load values. Can be a path
|
||||
* (file or dir), or URL (config server).
|
||||
*/
|
||||
void initialize_settings(std::string config_source = "");
|
||||
void initialize_settings(
|
||||
std::string config_source = "",
|
||||
bts::log::Level console_log_level = bts::Warn,
|
||||
bts::log::Level file_log_level = bts::Info);
|
||||
|
||||
int load(const std::string &url, ConfigLog &);
|
||||
int load_string(const std::string &values, bool print_errors = false);
|
||||
|
||||
@@ -27,14 +27,24 @@ internal::ConfigurationState config_state;
|
||||
// Public API
|
||||
//////////////////////////////////////////
|
||||
|
||||
extern "C" BTS_EXPORT void initialize(const char *config_source) {
|
||||
config_state.initialize_settings(string{config_source});
|
||||
extern "C" BTS_EXPORT void initialize(
|
||||
const char *config_source,
|
||||
std::int16_t console_log_level,
|
||||
std::int16_t file_log_level) {
|
||||
config_state.initialize_settings(
|
||||
string{config_source},
|
||||
bts::log::Level{static_cast<std::uint8_t>(console_log_level)},
|
||||
bts::log::Level{static_cast<std::uint8_t>(file_log_level)});
|
||||
}
|
||||
|
||||
extern "C" BTS_EXPORT bool initialize_nothrow(
|
||||
const char *config_source, char *error_message, size_t len) {
|
||||
const char *config_source,
|
||||
char *error_message,
|
||||
size_t len,
|
||||
std::int16_t console_log_level,
|
||||
std::int16_t file_log_level) {
|
||||
try {
|
||||
initialize(config_source);
|
||||
initialize(config_source, console_log_level, file_log_level);
|
||||
} catch (std::exception &e) {
|
||||
std::string msg = e.what();
|
||||
if (msg.size() < len) {
|
||||
|
||||
@@ -27,12 +27,19 @@ namespace config {
|
||||
// config can result in network requests this function is available for
|
||||
// applications that want to manage pauses in execution. Ex: initialize() on a
|
||||
// background thread so that config::get<T>() is fast on a UI thread
|
||||
extern "C" BTS_EXPORT void initialize(const char *config_path);
|
||||
extern "C" BTS_EXPORT void initialize(
|
||||
const char *config_path,
|
||||
std::int16_t console_log_level,
|
||||
std::int16_t file_log_level);
|
||||
|
||||
// Calls initialize() but catches any thrown exception and copies it to the
|
||||
// provided buffer
|
||||
extern "C" BTS_EXPORT bool initialize_nothrow(
|
||||
const char *config_source, char *error_msg, size_t length);
|
||||
const char *config_source,
|
||||
char *error_msg,
|
||||
size_t length,
|
||||
std::int16_t console_log_level,
|
||||
std::int16_t file_log_level);
|
||||
|
||||
std::vector<const google::protobuf::FieldDescriptor *> get_fields(
|
||||
const std::vector<std::string> keys = {},
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
cmake_minimum_required(VERSION 3.23)
|
||||
project(bts-system)
|
||||
include(${CMAKE_SOURCE_DIR}/cmake/InitLibrary.cmake)
|
||||
init_library(system)
|
||||
|
||||
# fmt
|
||||
find_package(fmt CONFIG REQUIRED)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC fmt::fmt)
|
||||
@@ -0,0 +1,8 @@
|
||||
#include "foo.h"
|
||||
#include <fmt/format.h>
|
||||
|
||||
namespace bts::system {
|
||||
void Foo:: say_hello() {
|
||||
std::cout << fmt::format("Hi, my name is {}", name) << std::endl;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
namespace bts::system {
|
||||
|
||||
struct Foo {
|
||||
std::string name;
|
||||
void say_hello();
|
||||
};
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user