Skip to content

Commit d255d1a

Browse files
committed
Add multiplayer abstractions
Add multi-platform socket abstractions Add Udp and Tcp client/server socket handlers Add RingBuffer Add PacketReaderAdapter Add PacketBuilder Deduplicate stack_string behaviors into StackString Add `GameManager::get_elapsed_microseconds` Add `GameManager::get_elapsed_milliseconds` Add RingBuffer tests Add IpAddress tests Add UdpServer tests Add TcpServer tests Add mas-bandwidth/reliable@57b0c90
1 parent 91c33aa commit d255d1a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+6875
-172
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,6 @@
2626
[submodule "tests/benchmarks/deps/nanobench"]
2727
path = tests/benchmarks/deps/nanobench
2828
url = https://github.com/Spartan322/nanobench
29+
[submodule "deps/reliable"]
30+
path = deps/reliable
31+
url = https://github.com/mas-bandwidth/reliable

deps/SCsub

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,36 @@ def build_std_function(env):
4545
env.Append(CPPPATH=env.std_function["INCPATH"])
4646
env.exposed_includes += env.std_function["INCPATH"]
4747

48+
def build_reliable(env):
49+
import os
50+
51+
if env["dev_build"]:
52+
env.Append(CPPDEFINES=["RELIABLE_DEBUG"])
53+
else:
54+
env.Append(CPPDEFINES=["RELIABLE_RELEASE"])
55+
reliable_env = env.Clone()
56+
57+
include_path = "reliable"
58+
include_dir = env.Dir(include_path)
59+
sources = env.GlobRecursive("*.cpp", [include_path])
60+
env.reliable_sources = sources
61+
library_name = "libreliable" + env["LIBSUFFIX"]
62+
library = reliable_env.StaticLibrary(target=os.path.join(include_path, library_name), source=sources)
63+
Default(library)
64+
65+
env.reliable = {}
66+
env.reliable["INCPATH"] = [include_dir]
67+
68+
env.Append(CPPPATH=env.reliable["INCPATH"])
69+
if env.get("is_msvc", False):
70+
env.Append(CXXFLAGS=["/external:I", include_dir, "/external:W0"])
71+
else:
72+
env.Append(CXXFLAGS=["-isystem", include_dir])
73+
env.Append(LIBPATH=include_dir)
74+
env.Prepend(LIBS=[library_name])
75+
76+
env.exposed_includes += env.reliable["INCPATH"]
77+
4878
def link_tbb(env):
4979
import sys
5080
if not env.get("is_msvc", False) and not env.get("use_mingw", False) and sys.platform != "darwin":
@@ -56,4 +86,5 @@ build_ordered_map(env)
5686
build_colony(env)
5787
build_function2(env)
5888
build_std_function(env)
89+
build_reliable(env)
5990
link_tbb(env)

deps/reliable

Submodule reliable added at 57b0c90

src/headless/main.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,12 @@ static std::chrono::nanoseconds run_pathing_test(AStarPathing& pathing) {
112112
static bool run_headless(Dataloader::path_vector_t const& roots, bool run_tests) {
113113
bool ret = true;
114114

115-
GameManager game_manager { []() {
116-
Logger::info("State updated");
117-
} };
115+
GameManager game_manager {
116+
[] {
117+
Logger::info("State updated");
118+
},
119+
nullptr, nullptr
120+
};
118121

119122
Logger::info("Commit hash: ", GameManager::get_commit_hash());
120123

src/openvic-simulation/GameManager.cpp

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,39 @@
11
#include "GameManager.hpp"
22

3+
#include <chrono>
4+
35
using namespace OpenVic;
46

7+
static std::chrono::time_point elapsed_time_begin = std::chrono::high_resolution_clock::now();
8+
9+
GameManager::elapsed_time_getter_func_t GameManager::get_elapsed_usec_time_callback = []() -> uint64_t {
10+
std::chrono::time_point current = std::chrono::high_resolution_clock::now();
11+
return std::chrono::duration_cast<std::chrono::microseconds>(current - elapsed_time_begin).count();
12+
};
13+
14+
GameManager::elapsed_time_getter_func_t GameManager::get_elapsed_msec_time_callback = []() -> uint64_t {
15+
std::chrono::time_point current = std::chrono::high_resolution_clock::now();
16+
return std::chrono::duration_cast<std::chrono::milliseconds>(current - elapsed_time_begin).count();
17+
};
18+
519
GameManager::GameManager(
6-
InstanceManager::gamestate_updated_func_t new_gamestate_updated_callback
20+
InstanceManager::gamestate_updated_func_t new_gamestate_updated_callback,
21+
elapsed_time_getter_func_t new_get_elapsed_usec_callback,
22+
elapsed_time_getter_func_t new_get_elapsed_msec_callback
723
) : gamestate_updated_callback {
824
new_gamestate_updated_callback ? std::move(new_gamestate_updated_callback) : []() {}
9-
}, definitions_loaded { false } {}
25+
}, definitions_loaded { false } {
26+
if (new_get_elapsed_usec_callback) {
27+
get_elapsed_usec_time_callback = { std::move(new_get_elapsed_usec_callback) };
28+
}
29+
if (new_get_elapsed_msec_callback) {
30+
get_elapsed_msec_time_callback = { std::move(new_get_elapsed_msec_callback) };
31+
}
32+
33+
if (bool(new_get_elapsed_usec_callback) != bool(new_get_elapsed_msec_callback)) {
34+
Logger::warning("Only one of the elapsed time callbacks was set.");
35+
}
36+
}
1037

1138
bool GameManager::set_roots(Dataloader::path_vector_t const& roots) {
1239
if (!dataloader.set_roots(roots)) {
@@ -84,3 +111,11 @@ bool GameManager::update_clock() {
84111

85112
return instance_manager->update_clock();
86113
}
114+
115+
uint64_t GameManager::get_elapsed_microseconds() {
116+
return get_elapsed_usec_time_callback();
117+
}
118+
119+
uint64_t GameManager::get_elapsed_milliseconds() {
120+
return get_elapsed_msec_time_callback();
121+
}

src/openvic-simulation/GameManager.hpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,16 @@
88
#include "openvic-simulation/misc/GameRulesManager.hpp"
99
#include "openvic-simulation/gen/commit_info.gen.hpp"
1010

11+
#include <function2/function2.hpp>
12+
1113
namespace OpenVic {
1214
struct GameManager {
15+
using elapsed_time_getter_func_t = fu2::function_base<true, true, fu2::capacity_none, false, false, uint64_t() const>;
16+
1317
private:
18+
static elapsed_time_getter_func_t get_elapsed_usec_time_callback;
19+
static elapsed_time_getter_func_t get_elapsed_msec_time_callback;
20+
1421
GameRulesManager PROPERTY(game_rules_manager);
1522
Dataloader PROPERTY(dataloader);
1623
DefinitionManager PROPERTY(definition_manager);
@@ -21,7 +28,9 @@ namespace OpenVic {
2128

2229
public:
2330
GameManager(
24-
InstanceManager::gamestate_updated_func_t new_gamestate_updated_callback
31+
InstanceManager::gamestate_updated_func_t new_gamestate_updated_callback,
32+
elapsed_time_getter_func_t new_get_elapsed_usec_callback,
33+
elapsed_time_getter_func_t new_get_elapsed_msec_callback
2534
);
2635

2736
inline constexpr InstanceManager* get_instance_manager() {
@@ -49,5 +58,8 @@ namespace OpenVic {
4958
static constexpr uint64_t get_commit_timestamp() {
5059
return SIM_COMMIT_TIMESTAMP;
5160
}
61+
62+
static uint64_t get_elapsed_microseconds();
63+
static uint64_t get_elapsed_milliseconds();
5264
};
5365
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
2+
#include "HostnameAddress.hpp"
3+
4+
#include <charconv>
5+
#include <system_error>
6+
7+
#include "openvic-simulation/multiplayer/IpAddress.hpp"
8+
#include "openvic-simulation/multiplayer/NetworkResolver.hpp"
9+
10+
using namespace OpenVic;
11+
12+
HostnameAddress::HostnameAddress() = default;
13+
14+
HostnameAddress::HostnameAddress(IpAddress const& address) : _resolved_address(address) {}
15+
16+
HostnameAddress::HostnameAddress(std::string_view name_or_address) : HostnameAddress() {
17+
std::from_chars_result result =
18+
_resolved_address.from_chars(name_or_address.data(), name_or_address.data() + name_or_address.size());
19+
if (result.ec != std::errc {}) {
20+
_resolved_address = NetworkResolver::singleton().resolve_hostname(name_or_address);
21+
}
22+
}
23+
24+
IpAddress const& HostnameAddress::resolved_address() const {
25+
return _resolved_address;
26+
}
27+
28+
void HostnameAddress::set_resolved_address(IpAddress const& address) {
29+
_resolved_address = address;
30+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#pragma once
2+
3+
#include <string_view>
4+
5+
#include "openvic-simulation/multiplayer/IpAddress.hpp"
6+
7+
namespace OpenVic {
8+
struct HostnameAddress {
9+
HostnameAddress();
10+
HostnameAddress(IpAddress const& address);
11+
HostnameAddress(std::string_view name_or_address);
12+
13+
IpAddress const& resolved_address() const;
14+
void set_resolved_address(IpAddress const& address);
15+
16+
private:
17+
IpAddress _resolved_address;
18+
};
19+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#include "IpAddress.hpp"
2+
3+
#include <string>
4+
5+
using namespace OpenVic;
6+
7+
std::string IpAddress::to_string(bool prefer_ipv4, to_chars_option option) const {
8+
stack_string result = to_array(prefer_ipv4, option);
9+
if (OV_unlikely(result.empty())) {
10+
return {};
11+
}
12+
13+
return result;
14+
}
15+
16+
IpAddress::operator std::string() const {
17+
return to_string();
18+
}

0 commit comments

Comments
 (0)