Skip to content
This repository has been archived by the owner on Aug 31, 2022. It is now read-only.

Commit

Permalink
Add network system
Browse files Browse the repository at this point in the history
  • Loading branch information
Henrik0x7F committed Jul 25, 2020
1 parent 6d1e7b2 commit 0a429d3
Show file tree
Hide file tree
Showing 113 changed files with 2,503 additions and 732 deletions.
6 changes: 5 additions & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,8 @@

[submodule "externals/open-vcdiff"]
path = externals/open-vcdiff
url = https://github.com/google/open-vcdiff.git
url = https://github.com/google/open-vcdiff.git

[submodule "externals/cereal"]
path = externals/cereal
url = https://github.com/USCiLab/cereal.git
4 changes: 2 additions & 2 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ git_get_exact_tag(GIT_TAG)
set(GIT_REVISION_FILE "${CMAKE_CURRENT_BINARY_DIR}/src/build_info.cpp")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/build_info.cpp.in" "${GIT_REVISION_FILE}" @ONLY)

include_directories(src externals externals/mem64/include)
include_directories(src externals/mem64/include externals/spdlog-lib externals/m64plus-headers)

option(BUILD_CORE "Build core library" ON)
option(BUILD_QT_FRONTEND "Build the Qt5 userinterface" ON)
Expand All @@ -40,6 +40,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install")

if(BUILD_CORE)
include_directories(externals/cereal/include)
add_subdirectory(src/net64)
endif()

Expand Down
1 change: 1 addition & 0 deletions externals/cereal
Submodule cereal added at 02eace
2 changes: 1 addition & 1 deletion externals/mem64
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
127 changes: 127 additions & 0 deletions src/common/automatic_factory.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@

//
// Created by henrik on 16.05.19.
// Copyright 2020 Net64 Coop Project
// Licensed under GPLv3
// Refer to the LICENSE file included
//

#pragma once

#include <memory>
#include <type_traits>
#include <unordered_map>


template<typename TBase, typename TKey, typename TPtr = std::unique_ptr<TBase>, typename... TArgs>
struct Factory
{
using FactoryType = TBase* (*)(TArgs&&... args);

friend TBase;

protected:
Factory() = default;

struct Shared
{
template<typename, auto, bool>
friend struct RegisterConst;
template<typename, bool>
friend struct RegisterDyn;
friend Factory;

private:
static std::unordered_map<TKey, FactoryType>& get_factories()
{
static std::unordered_map<TKey, FactoryType> s_factories;
return s_factories;
}
};

static const std::unordered_map<TKey, FactoryType>& get_factories() { return Shared::get_factories(); }

protected:
using Identifier = TKey;

template<typename T, T>
struct DummyUser
{
};

public:
template<typename, auto, bool>
friend struct RegisterConst;
template<typename, bool>
friend struct RegisterDyn;

[[nodiscard]] static TPtr make(const TKey& key, TArgs&&... args)
{
static_assert(std::is_base_of_v<Factory<TBase, TKey, TPtr, TArgs...>, TBase>,
"Trying to instantiate derived class of non-registry");
return TPtr{Shared::get_factories().at(key)(std::forward<TArgs>(args)...)};
}

[[nodiscard]] static TPtr make(std::string_view key, TArgs&&... args)
{
return make(std::string(key), std::forward<TArgs>(args)...);
}

struct Empty
{
};

template<typename TRegistrar, auto KEY, bool INHERIT_FROM_BASE = true>
struct RegisterConst : std::conditional_t<INHERIT_FROM_BASE, TBase, Empty>
{
friend TRegistrar;

private:
using Base = std::conditional_t<INHERIT_FROM_BASE, TBase, Empty>;
using Base::Base;

struct Private
{
friend RegisterConst;

private:
static bool register_class()
{
Shared::get_factories()[TKey{KEY}] = [](TArgs&&... args) -> TBase* {
return new TRegistrar(std::forward<TArgs>(args)...);
};
return true;
}
};

[[maybe_unused]] inline static bool s_registered{Private::register_class()};
using ValueUser = DummyUser<const bool*, &s_registered>;
};

template<typename TRegistrar, bool INHERIT_FROM_BASE = true>
struct RegisterDyn : std::conditional_t<INHERIT_FROM_BASE, TBase, Empty>
{
friend TRegistrar;

private:
using Base = std::conditional_t<INHERIT_FROM_BASE, TBase, Empty>;
using Base::Base;

struct Private
{
friend RegisterDyn;

private:
static bool register_class()
{
Shared::get_factories()[TKey{TRegistrar::get_key()}] = [](TArgs&&... args) -> TBase* {
return new TRegistrar(std::forward<TArgs>(args)...);
};
return true;
}
};

[[maybe_unused]] inline static bool s_registered{Private::register_class()};
using ValueUser = DummyUser<const bool*, &s_registered>;
};
};
7 changes: 1 addition & 6 deletions src/common/badge.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,11 @@
#pragma once


namespace Common
{

template<typename T>
struct Badge
{
friend T;

private:
Badge(){}
Badge() {}
};

} // Common
141 changes: 141 additions & 0 deletions src/common/double_dispatch.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@

//
// Created by henrik on 17.11.19.
// Copyright 2020 Net64 Coop Project
// Licensed under GPLv3
// Refer to the LICENSE file included
//

#pragma once

#include <type_traits>
#include <typeinfo>
#include <utility>


template<typename... UsrArgs>
struct DoubleDispatcher
{
private:
struct TypeIdPredicate
{
template<typename Concrete, typename Base>
bool check(const Base& base)
{
return (typeid(base) == typeid(Concrete));
}
};

struct DynamicCastPredicate
{
template<typename Concrete, typename Base>
bool check(const Base& base)
{
return (dynamic_cast<const Concrete*>(&base) != nullptr);
}
};

template<typename Base, typename Concrete>
struct AddQualifiers;

template<typename Base, typename Concrete>
struct AddQualifiers<Base*, Concrete>
{
using type = Concrete*;
};
template<typename Base, typename Concrete>
struct AddQualifiers<Base&, Concrete>
{
using type = Concrete&;
};
template<typename Base, typename Concrete>
struct AddQualifiers<const Base*, Concrete>
{
using type = const Concrete*;
};

template<typename Base, typename Concrete>
struct AddQualifiers<const Base&, Concrete>
{
using type = const Concrete&;
};

template<typename T>
static T& deref(T* v)
{
return *v;
}

template<typename T>
static T& deref(T& v)
{
return v;
}

public:
/**
* Wrapper of custom_dispatch with Predicate = TypeIdPredicate
* Calls Handler::on_dispatch(Type) for every type whose runtime type is Type
* Rejects any type that is not explicitly specified in ConcreteTypes, even if it is a derivative of one
* If you also want to receive types which inherit from a specified type, use relaxed_dispatch
* See custom_dispatch for documentation of parameters
*/
template<typename Handler, typename BaseType, typename... ConcreteTypes>
static bool strict_dispatch(Handler handler, BaseType param, UsrArgs... args)
{
return double_dispatch<Handler, TypeIdPredicate, BaseType, ConcreteTypes...>(
handler, param, TypeIdPredicate(), std::forward<UsrArgs>(args)...);
}

/**
* Wrapper of custom_dispatch with Predicate = DynamicCastPredicate
* Calls Handler::on_dispatch(Type) for every type whose runtime type is Type or a derivative of Type
* See custom_dispatch for documentation of parameters
*/
template<typename Handler, typename BaseType, typename... ConcreteTypes>
static bool relaxed_dispatch(Handler handler, BaseType param, UsrArgs... args)
{
return double_dispatch<Handler, DynamicCastPredicate, BaseType, ConcreteTypes...>(
handler, param, DynamicCastPredicate(), std::forward<UsrArgs>(args)...);
}

/**
* Calls Handler::on_dispatch(Type) with the correct concrete type of param
* @tparam Handler Type to call the concrete methods on
* @tparam Predicate Functor with bool check<ConcreteType>(BaseType) method to determine if BaseType can be casted
* to ConcreteType
* @tparam BaseType Base of all dispatched types. This type should be fully qualified (e.g. const, pointer /
* reference)
* @tparam ConcreteTypes List of all types a concrete function is provided for. These should not be qualified
* @param handler Object to call concrete methods on
* @param param Base object to dispatch
* @param pred Functor of type Predicate
* @return True if a matching concrete function for the runtime type of param was found
*/
template<typename Handler, typename Predicate, typename BaseType, typename... ConcreteTypes>
static bool custom_dispatch(Handler handler, BaseType param, Predicate pred, UsrArgs... args)
{
return double_dispatch<Handler, Predicate, BaseType, ConcreteTypes...>(
handler, param, pred, std::forward<UsrArgs>(args)...);
}

private:
template<typename Handler, typename Predicate, typename BaseType, typename DerivedType, typename... DerivedTypes>
static bool double_dispatch(Handler handler, BaseType param, Predicate pred, UsrArgs... args)
{
if(pred.template check<DerivedType>(deref(param)))
{
handler.on_dispatch(static_cast<typename AddQualifiers<BaseType, DerivedType>::type>(param),
std::forward<UsrArgs>(args)...);
return true;
}
return double_dispatch<Handler, Predicate, BaseType, DerivedTypes...>(
handler, param, pred, std::forward<UsrArgs>(args)...);
}

template<typename Handler, typename Predicate, typename BaseType>
static bool double_dispatch(Handler, BaseType, Predicate, UsrArgs...)
{
return false;
}
};
Loading

0 comments on commit 0a429d3

Please sign in to comment.