Compare commits

..

16 Commits

Author SHA1 Message Date
4a40c38686 workflow build&test 3 2026-03-02 21:15:12 +03:00
9955c1986c workflow build&test 2
All checks were successful
Verification / Is-Buildable (push) Successful in 2m5s
2026-03-02 21:09:12 +03:00
15fb311c66 workflow build&test
Some checks failed
Verification / Is-Buildable (push) Failing after 1m52s
2026-03-02 21:00:34 +03:00
5c5b886360 build test 12
All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 1m50s
2026-03-02 20:46:39 +03:00
1eea074051 build test 11
Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 4s
2026-03-02 20:44:38 +03:00
626cfa64f2 build test 10
Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 1m6s
2026-03-02 20:38:50 +03:00
00da1c9f32 build test 9
Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 1m6s
2026-03-02 20:36:19 +03:00
c5ede14eaf build test 8
Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 13s
2026-03-02 20:35:18 +03:00
981568f104 build test 7
Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 39s
2026-03-02 20:32:48 +03:00
638c565702 build test 6
Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 27s
2026-03-02 20:31:46 +03:00
81f8f709a2 build test 5
Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 11s
2026-03-02 20:31:01 +03:00
6fea0e2450 build test 4
Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 21s
2026-03-02 20:27:36 +03:00
e881b6b699 build test 3
Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 20s
2026-03-02 20:26:30 +03:00
2157b25a95 build test 2
Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 6s
2026-03-02 20:25:25 +03:00
f2dfee7a38 build test
Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 10s
2026-03-02 20:21:48 +03:00
5afbf771ca test
All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 1m27s
2026-03-02 20:16:25 +03:00
29 changed files with 43 additions and 160 deletions

1
.gitignore vendored
View File

@ -6,5 +6,4 @@ subprojects/googletest-*
subprojects/nlohmann_json/
subprojects/packagecache/
subprojects/yaml-cpp-0.8.0
subprojects/base64-0.5.2/
.venv/

View File

@ -4,7 +4,7 @@ Communication JSON RPC protocol and implementation with Unity Scene.
## TODO
- [x] Server implementation with C-API for Unity
- [ ] Server implementation with C-API for Unity
- [ ] Client correct implementation with OpenCV
## API Documentation

View File

@ -3,7 +3,7 @@
#include <iostream>
#include <string>
#include "export.h"
namespace score {
namespace cloud_point_rpc {
/**
* @brief Runs the CLI client.

View File

@ -6,11 +6,11 @@
#include <vector>
#include <yaml-cpp/yaml.h>
namespace score {
namespace cloud_point_rpc {
struct ServerConfig {
std::string ip;
int port{0};
int port;
};
struct TestData {

View File

@ -6,7 +6,7 @@
#include <jsonrpccxx/client.hpp>
#include <nlohmann/json.hpp>
#include <vector>
namespace score {
namespace cloud_point_rpc {
class RpcClient : public jsonrpccxx::JsonRpcClient {
public:

View File

@ -1,27 +0,0 @@
//
// Created by vptyp on 11.03.2026.
//
#pragma once
#include <string>
#include <vector>
namespace score {
class IRPCCoder {
public:
virtual ~IRPCCoder() = default;
virtual std::vector<char> decode(const std::string& encoded) = 0;
virtual std::string encode(const std::vector<char>& data) = 0;
};
class Base64RPCCoder final : public IRPCCoder {
public:
Base64RPCCoder();
~Base64RPCCoder() override;
std::vector<char> decode(const std::string& encoded) override;
std::string encode(const std::vector<char>& data) override;
};
}

View File

@ -16,7 +16,7 @@ struct rpc_string {
};
}
namespace score {
namespace cloud_point_rpc {
class CRPC_EXPORT RpcServer {
public:

View File

@ -5,7 +5,7 @@
#include <type_traits>
#include <vector>
namespace score {
namespace cloud_point_rpc {
template <typename T>
concept NumericType = requires(T param) {

View File

@ -3,7 +3,7 @@
#include "cloud_point_rpc/config.hpp"
#include <vector>
#include "export.h"
namespace score {
namespace cloud_point_rpc {
class CRPC_EXPORT Service {
public:

View File

@ -6,7 +6,7 @@
#include <glog/logging.h>
#include <string>
#include "export.h"
namespace score {
namespace cloud_point_rpc {
/**
* TCPConnector main purpose is to implement jsonrpccxx::IClientConnector Send
* method As an internal implementation, TCPConnector adds to the beginning of

View File

@ -3,7 +3,7 @@
#include <asio.hpp>
#include <cloud_point_rpc/serialize.hpp>
#include <glog/logging.h>
namespace score {
namespace cloud_point_rpc {
static inline std::string tcp_read(asio::ip::tcp::socket &socket,
std::string_view prefix) {

View File

@ -10,7 +10,7 @@
#include "export.h"
#include <list>
#include <ranges>
namespace score {
namespace cloud_point_rpc {
class CRPC_EXPORT TcpServer {
public:

View File

@ -6,7 +6,7 @@ project('cloud_point_rpc', 'cpp',
json_dep = dependency('nlohmann_json', fallback : ['nlohmann_json', 'nlohmann_json_dep'])
thread_dep = dependency('threads')
asio_dep = dependency('asio', fallback : ['asio', 'asio_dep'])
base64_dep = dependency('base64', fallback: ['aklomp-base64', 'base64'])
# GLog via CMake fallback
cmake = import('cmake')
glog_opt = cmake.subproject_options()

View File

@ -3,7 +3,7 @@
#include <glog/logging.h>
#include <string>
namespace score {
namespace cloud_point_rpc {
void print_menu(std::ostream &output) {
output << "\n=== Cloud Point RPC CLI ===" << std::endl;

View File

@ -24,8 +24,8 @@ int main(int argc, char *argv[]) {
f.close();
try {
auto config = score::ConfigLoader::load(config_path);
return score::run_cli(std::cin, std::cout, config.server.ip,
auto config = cloud_point_rpc::ConfigLoader::load(config_path);
return cloud_point_rpc::run_cli(std::cin, std::cout, config.server.ip,
config.server.port);
} catch (const std::exception &e) {
std::cerr << "Failed to start CLI: " << e.what() << std::endl;

View File

@ -3,20 +3,19 @@ add_project_arguments('-DCRPC_SERVER_API_EXPORT -pthread', language: 'cpp')
cloud_point_rpc_sources = files(
'rpc_server.cpp',
'service.cpp',
'server_api.cpp',
'rpc_coder.cpp'
'server_api.cpp'
)
libcloud_point_rpc = shared_library('cloud_point_rpc',
cloud_point_rpc_sources,
include_directories : inc,
dependencies : [json_dep, thread_dep, glog_dep, yaml_dep, asio_dep, base64_dep],
dependencies : [json_dep, thread_dep, glog_dep, yaml_dep, asio_dep],
install : true)
cloud_point_rpc_dep = declare_dependency(
include_directories : inc,
link_with : libcloud_point_rpc,
dependencies : [json_dep, glog_dep, yaml_dep, asio_dep, base64_dep])
dependencies : [json_dep, glog_dep, yaml_dep, asio_dep])
# Test lib
libcloud_point_rpc_test = shared_library('test_cloud_point',
@ -33,7 +32,7 @@ cloud_point_rpc_test_dep = declare_dependency(
libcloud_point_rpc_cli = shared_library('libcloud_point_rpc_cli',
'cli.cpp',
include_directories : inc,
dependencies : [cloud_point_rpc_dep],
dependencies : [json_dep, thread_dep, glog_dep, yaml_dep, asio_dep, cloud_point_rpc_dep],
install : true)
cloud_point_rpc_cli_dep = declare_dependency(

View File

@ -1,42 +0,0 @@
//
// Created by vptyp on 11.03.2026.
//
#include "cloud_point_rpc/rpc_coder.h"
#include "libbase64.h"
#include <glog/logging.h>
namespace score {
Base64RPCCoder::Base64RPCCoder() = default;
Base64RPCCoder::~Base64RPCCoder() = default;
/**
* Tries to decode ASCII complained string to the
* @param encoded ASCII complained base64 encoded string
* @return vector of raw bytes << allocated on encoded.size() / 4 * 3 + 1 size
*/
std::vector<char> Base64RPCCoder::decode(const std::string& encoded) {
DLOG(INFO) << "Base64RPCCoder::decode";
std::vector<char> result((encoded.length() >> 2) * 3 + 1);
size_t result_len = 0;
base64_decode(encoded.data(), encoded.size(),
result.data(), &result_len, 0);
DLOG(INFO) << "result_len: " << result_len;
return result;
}
/**
*
* @param data raw byte stream
* @return encoded base64 string
*/
std::string Base64RPCCoder::encode(const std::vector<char>& data) {
DLOG(INFO) << "Base64RPCCoder::encode";
size_t result_len = 0;
std::string result(data.size() / 3 * 4 + 1, 0);
base64_encode(data.data(), data.size(),
result.data(), &result_len, 0
);
DLOG(INFO) << "result_len: " << result_len;
return result;
}
}

View File

@ -2,7 +2,7 @@
#include <glog/logging.h>
using json = nlohmann::json;
namespace score {
namespace cloud_point_rpc {
namespace {
json create_error(int code, const std::string &message,

View File

@ -9,8 +9,8 @@
#include <list>
static std::list<std::unique_ptr<rpc_string>> gc;
score::RpcServer rpc_server;
std::unique_ptr<score::TcpServer> server = nullptr;
cloud_point_rpc::RpcServer rpc_server;
std::unique_ptr<cloud_point_rpc::TcpServer> server = nullptr;
extern "C" {
@ -40,10 +40,10 @@ void crpc_init(const char* config_path) {
LOG(INFO) << "config_path was not provided";
}
try {
auto config = score::ConfigLoader::load(config_path);
auto config = cloud_point_rpc::ConfigLoader::load(config_path);
LOG(INFO) << "Loaded config from " << config_path;
server = std::make_unique<score::TcpServer>(config.server.ip, config.server.port,
server = std::make_unique<cloud_point_rpc::TcpServer>(config.server.ip, config.server.port,
[&](const std::string &request) {
return rpc_server.process(
request);

View File

@ -20,12 +20,12 @@ int main(int argc, char *argv[]) {
LOG(INFO) << "Starting Cloud Point RPC Server (Test Mock)...";
try {
auto config = score::ConfigLoader::load(config_path);
auto config = cloud_point_rpc::ConfigLoader::load(config_path);
LOG(INFO) << "Loaded config from " << config_path;
// Inject test data into service
score::Service service(config.test_data);
score::RpcServer rpc_server;
cloud_point_rpc::Service service(config.test_data);
cloud_point_rpc::RpcServer rpc_server;
rpc_server.register_method("get-intrinsic-params", [&](const json &) {
return service.get_intrinsic_params();
@ -39,7 +39,7 @@ int main(int argc, char *argv[]) {
return service.get_cloud_point();
});
score::TcpServer server(config.server.ip, config.server.port,
cloud_point_rpc::TcpServer server(config.server.ip, config.server.port,
[&](const std::string &request) {
return rpc_server.process(
request);

View File

@ -1,6 +1,6 @@
#include "cloud_point_rpc/service.hpp"
namespace score {
namespace cloud_point_rpc {
Service::Service(const TestData &data) : data_(data) {}

View File

@ -121,7 +121,7 @@ class TestThread {
calls_queue = std::queue<std::string>();
methods.clear();
state.store(true, std::memory_order_relaxed);
server = score::RpcServer();
server = cloud_point_rpc::RpcServer();
}
private:
@ -131,7 +131,7 @@ class TestThread {
std::set<std::string> methods{};
std::jthread thr;
std::mutex mtx;
score::RpcServer server;
cloud_point_rpc::RpcServer server;
std::chrono::duration<int64_t, std::milli> thr_sleep{50};
} test;

View File

@ -1,14 +0,0 @@
[wrap-file]
directory = base64-0.5.2
source_url = https://github.com/aklomp/base64/archive/refs/tags/v0.5.2.tar.gz
source_filename = base64-0.5.2.tar.gz
source_hash = 723a0f9f4cf44cf79e97bcc315ec8f85e52eb104c8882942c3f2fba95acc080d
source_fallback_url = https://wrapdb.mesonbuild.com/v2/aklomp-base64_0.5.2-1/get_source/base64-0.5.2.tar.gz
patch_filename = aklomp-base64_0.5.2-1_patch.zip
patch_url = https://wrapdb.mesonbuild.com/v2/aklomp-base64_0.5.2-1/get_patch
patch_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/aklomp-base64_0.5.2-1/aklomp-base64_0.5.2-1_patch.zip
patch_hash = 9805354b8c0333fe0123c10d8c62356ef1d0d67a2689a348d18f73bddc1e2b10
wrapdb_version = 0.5.2-1
[provide]
dependency_names = base64

View File

@ -3,8 +3,7 @@ test_sources = files(
'test_integration.cpp',
'test_tcp.cpp',
'test_cli.cpp',
'test_c_api.cpp',
'test_base64.cpp'
'test_c_api.cpp'
)
test_exe = executable('unit_tests',

View File

@ -1,31 +0,0 @@
//
// Created by vptyp on 11.03.2026.
//
#include <chrono>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <thread>
#include "cloud_point_rpc/config.hpp"
#include "cloud_point_rpc/rpc_coder.h"
class Base64Test : public ::testing::Test {
protected:
void SetUp() override {
}
void TearDown() override {
}
};
TEST_F(Base64Test, EncodeDecode) {
std::vector raw{'H', 'e', 'l', 'l', 'o', 'w', '\0'};
score::Base64RPCCoder coder;
auto encoded = coder.encode(raw);
LOG(INFO) << "encoded: " << encoded;
auto decoded = coder.decode(encoded);
EXPECT_EQ(std::ranges::equal(decoded, raw), true);
LOG(INFO) << "done";
}

View File

@ -9,7 +9,7 @@
#include "cloud_point_rpc/rpc_server.hpp"
#include "cloud_point_rpc/tcp_server.hpp"
using namespace score;
using namespace cloud_point_rpc;
class CliTest : public ::testing::Test {
public:

View File

@ -11,7 +11,7 @@
#include <fstream>
using namespace score;
using namespace cloud_point_rpc;
class IntegrationTest : public ::testing::Test {
protected:
@ -69,7 +69,7 @@ class IntegrationTest : public ::testing::Test {
std::remove("config.yaml");
}
Config config_{};
Config config_;
std::unique_ptr<Service> service_;
std::unique_ptr<RpcServer> rpc_server_;
std::unique_ptr<TcpServer> tcp_server_;

View File

@ -7,7 +7,7 @@
#include <vector>
using json = nlohmann::json;
using namespace score;
using namespace cloud_point_rpc;
class RpcServerTest : public ::testing::Test {
protected:

View File

@ -15,11 +15,11 @@ class TcpTest : public ::testing::Test {
protected:
void SetUp() override {
server_ = std::make_unique<score::TcpServer>(
server_ = std::make_unique<cloud_point_rpc::TcpServer>(
"127.0.0.1", 12345, [this](const std::string &request) {
EXPECT_EQ(request, expected_);
std::string msg = "Echo: " + request;
auto v = score::serialize(msg.length());
auto v = cloud_point_rpc::serialize(msg.length());
std::string res(v.begin(), v.end());
res += msg;
return res;
@ -33,19 +33,19 @@ class TcpTest : public ::testing::Test {
}
std::string expected_;
std::unique_ptr<score::TcpServer> server_;
std::unique_ptr<cloud_point_rpc::TcpServer> server_;
};
TEST(SerializeTest, Base) {
uint64_t value{123};
auto res = score::serialize(value);
EXPECT_EQ(value, score::deserialize<uint64_t>(res));
auto res = cloud_point_rpc::serialize(value);
EXPECT_EQ(value, cloud_point_rpc::deserialize<uint64_t>(res));
}
TEST_F(TcpTest, EchoTest) {
constexpr std::string_view msg = "Hello, TCP Server!";
ExpectedResponse(msg.data());
score::TCPConnector connector("127.0.0.1", 12345);
cloud_point_rpc::TCPConnector connector("127.0.0.1", 12345);
auto res = connector.Send(msg.data());
}
@ -53,6 +53,6 @@ TEST_F(TcpTest, HugeBuffer) {
static constexpr uint64_t w = 1280, h = 720, c = 3;
std::string data(w * h * c, 77);
ExpectedResponse(data);
score::TCPConnector connector("127.0.0.1", 12345);
cloud_point_rpc::TCPConnector connector("127.0.0.1", 12345);
auto res = connector.Send(data);
}