Skip to content

Commit

Permalink
WIP code, pls don't review
Browse files Browse the repository at this point in the history
  • Loading branch information
Felk committed Jul 14, 2018
1 parent 3d41760 commit aa20c28
Show file tree
Hide file tree
Showing 20 changed files with 1,039 additions and 54 deletions.
1 change: 1 addition & 0 deletions Source/Core/Common/Common.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@
<ClInclude Include="Timer.h" />
<ClInclude Include="TraversalClient.h" />
<ClInclude Include="TraversalProto.h" />
<ClInclude Include="TupleUtil.h" />
<ClInclude Include="UPnP.h" />
<ClInclude Include="Version.h" />
<ClInclude Include="WorkQueueThread.h" />
Expand Down
3 changes: 2 additions & 1 deletion Source/Core/Common/Common.vcxproj.filters
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Crypto">
Expand Down Expand Up @@ -274,6 +274,7 @@
<ClInclude Include="Debug\MemoryPatches.h">
<Filter>Debug</Filter>
</ClInclude>
<ClInclude Include="TupleUtil.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="CDUtils.cpp" />
Expand Down
36 changes: 36 additions & 0 deletions Source/Core/Common/TupleUtil.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright 2018 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.

#pragma once

#include <tuple>

template <class F, typename Tuple, size_t... Is>
auto _TupleMapImpl(Tuple& t, F f, std::index_sequence<Is...>)
{
return std::make_tuple(f(std::get<Is>(t))...);
}

// returns a new tuple with each tuple item mapped by the given function.
// The tuple is passed by reference, so the mapping function may take references to the values.
template <class F, typename... Args>
auto TupleMap(std::tuple<Args...>& t, F f)
{
return _TupleMapImpl(t, f, std::make_index_sequence<sizeof...(Args)>{});
}


template <typename Tuple, size_t... Is>
static auto _TupleToArrayImpl(Tuple& t, std::index_sequence<Is...>)
{
return std::array<std::tuple_element_t<0, Tuple>, sizeof...(Is)>{std::get<Is>(t)...};
}

// turns a tuple consisting of 1 or more elements of the same type into a std::array
template <typename... Args>
static auto TupleToArray(std::tuple<Args...>& t)
{
return _TupleToArrayImpl(t, std::make_index_sequence<sizeof...(Args)>{});
}

3 changes: 3 additions & 0 deletions Source/Core/DolphinQt2/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "DolphinQt2/Updater.h"
#include "UICommon/CommandLineParse.h"
#include "UICommon/UICommon.h"
#include "Scripting/ScriptingEngine.h"

static bool QtMsgAlertHandler(const char* caption, const char* text, bool yes_no, MsgType style)
{
Expand Down Expand Up @@ -135,6 +136,7 @@ int main(int argc, char* argv[])
UICommon::Init();
Resources::Init();
Settings::Instance().SetBatchModeEnabled(options.is_set("batch"));
Scripting::Init();

// Hook up alerts from core
RegisterMsgAlertHandler(QtMsgAlertHandler);
Expand Down Expand Up @@ -216,6 +218,7 @@ int main(int argc, char* argv[])
retval = app.exec();
}

Scripting::Shutdown();
Core::Shutdown();
UICommon::Shutdown();
Host::GetInstance()->deleteLater();
Expand Down
64 changes: 64 additions & 0 deletions Source/Core/Scripting/Python/PyFramework/as_py_function.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright 2018 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.

#pragma once

#include <Python.h>
#include <tuple>
#include <iostream>

#include "Common/TupleUtil.h"

#include "Scripting/Python/PyFramework/fmt.h"


namespace Py
{


template <typename TRet, typename... TsArgs>
using Fun = TRet (*)(TsArgs...);

template <typename T, T>
struct WrapHelper;

template <typename TRet, typename... TsArgs, Fun<TRet, TsArgs...> TFun>
struct WrapHelper<Fun<TRet, TsArgs...>, TFun>
{
static PyObject* func(PyObject* self, PyObject* args)
{
std::tuple<TsArgs...> args_tpl;

std::tuple<PyObject*, const char*> py_args_and_fmt =
std::make_tuple(args, Py::fmts<TsArgs...>.c_str());
std::tuple<const TsArgs*...> args_pointers =
TupleMap(args_tpl, [](const auto& obj) { return &obj; });
auto invoke_args = std::tuple_cat(py_args_and_fmt, args_pointers);
if (!std::apply(PyArg_ParseTuple, invoke_args))
return nullptr;

if constexpr (std::is_same_v<TRet, void>)
{
std::apply(TFun, args_tpl);
Py_RETURN_NONE;
}
else
{
TRet result = std::apply(TFun, args_tpl);
return Py_BuildValue(Py::fmt<TRet>, result);
}

}
};

template <auto T>
struct Wrap : WrapHelper<decltype(T), T>
{
};

template <auto T>
static PyCFunction as_py_function = Wrap<T>::func;


} // namespace Py
115 changes: 115 additions & 0 deletions Source/Core/Scripting/Python/PyFramework/fmt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// Copyright 2018 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.

#pragma once

#include <Python.h>
#include <string>


namespace Py
{


// translates types to format strings according to the documentation:
// https://docs.python.org/3/c-api/arg.html
template <typename T>
constexpr const char* GetPyFmt()
{
static_assert(sizeof(T) != sizeof(T), "no python format string known for given type");
return nullptr;
}
#pragma region template specializations for each type
template <>
constexpr const char* GetPyFmt<signed char>()
{
return "b";
}
template <>
constexpr const char* GetPyFmt<signed short>()
{
return "h";
}
template <>
constexpr const char* GetPyFmt<signed int>()
{
return "i";
}
template <>
constexpr const char* GetPyFmt<signed long>()
{
return "l";
}
template <>
constexpr const char* GetPyFmt<signed long long>()
{
return "L";
}
template <>
constexpr const char* GetPyFmt<unsigned char>()
{
return "B";
}
template <>
constexpr const char* GetPyFmt<unsigned short>()
{
return "H";
}
template <>
constexpr const char* GetPyFmt<unsigned int>()
{
return "I";
}
template <>
constexpr const char* GetPyFmt<unsigned long>()
{
return "k";
}
template <>
constexpr const char* GetPyFmt<unsigned long long>()
{
return "K";
}
template <>
constexpr const char* GetPyFmt<float>()
{
return "f";
}
template <>
constexpr const char* GetPyFmt<double>()
{
return "d";
}
template <>
constexpr const char* GetPyFmt<PyObject*>()
{
return "O";
}
template <>
constexpr const char* GetPyFmt<char*>()
{
return "s";
}
#pragma endregion

template <typename T>
constexpr const char* fmt = GetPyFmt<T>();

template <typename TLast>
std::string GetPyFmts()
{
return std::string{fmt<TLast>};
}

template <typename TFirst, typename TSecond, typename... TRest>
std::string GetPyFmts()
{
return fmt<TFirst> + GetPyFmts<TSecond, TRest...>();
}

template <typename... Ts>
const std::string fmts = GetPyFmts<Ts...>();


} // namespace Py
48 changes: 48 additions & 0 deletions Source/Core/Scripting/Python/PyFramework/module.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright 2018 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.

#pragma once

#include <Python.h>
#include "Scripting/Python/PyFramework/as_py_function.h"

namespace Py
{


/*template <typename T>
struct FuncDef
{
char* func_name;
T func;
};*/

template <auto func>
constexpr PyMethodDef MakeMethodDef(const char* name)
{
const auto x = as_py_function<func>;
return {name, x, METH_VARARGS, ""};
}

/*constexpr PyModuleDef MakeModule(const char* module_name, PyMethodDef func_defs[])
{
return {PyModuleDef_HEAD_INIT, module_name, nullptr, -1, func_defs};
}*/

/*template <typename... Ts>
PyModuleDef MakeModule(const char* module_name, FuncDef<Ts>... func_defs)
{
std::tuple<decltype(func_defs)...> func_tpl{func_defs...};
auto py_funcs_tpl = TupleMap(func_tpl, [](auto& x) {
return {x.func_name, as_py_function<x.func>, METH_VARARGS, ""};
});
std::array<PyMethodDef, sizeof...(func_defs)> py_funcs = TupleToArray(py_funcs_tpl);
PyMethodDef Methods[] = {py_funcs};
return {PyModuleDef_HEAD_INIT, module_name, nullptr, -1, Methods};
}*/


} // namespace Py
Loading

0 comments on commit aa20c28

Please sign in to comment.