Skip to content
This repository has been archived by the owner on Apr 10, 2021. It is now read-only.

Commit

Permalink
DM api
Browse files Browse the repository at this point in the history
  • Loading branch information
1fbff5f83b23d39d38b1dfcb4cac8d9b committed Oct 18, 2019
1 parent 6bc2453 commit 38ef248
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 18 deletions.
7 changes: 0 additions & 7 deletions byond-extools/byond-extools.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,6 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="framework.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="src\core\core.h" />
<ClInclude Include="src\core\find_functions.h" />
<ClInclude Include="src\core\hooking.h" />
Expand All @@ -182,12 +181,6 @@
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="src\core\core.cpp" />
<ClCompile Include="src\core\find_functions.cpp" />
<ClCompile Include="src\core\hooking.cpp" />
Expand Down
6 changes: 0 additions & 6 deletions byond-extools/byond-extools.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@
<ClInclude Include="framework.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="pch.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\core\core.h">
<Filter>Header Files\core</Filter>
</ClInclude>
Expand Down Expand Up @@ -68,9 +65,6 @@
<ClCompile Include="dllmain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="pch.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\core\core.cpp">
<Filter>Source Files\core</Filter>
</ClCompile>
Expand Down
2 changes: 1 addition & 1 deletion byond-extools/dllmain.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include <Windows.h>

BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
Expand Down
12 changes: 10 additions & 2 deletions byond-extools/src/core/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,24 @@ unsigned int Core::register_opcode(std::string name, opcode_handler handler)
const char* good = "gucci";
const char* bad = "pain";

extern "C" __declspec(dllexport) const char* initialize(int n_args, const char* args)
extern "C" __declspec(dllexport) const char* core_initialize(int n_args, const char* args)
{
if (!Core::initialize())
{
MessageBoxA(NULL, "Core init failed!", "damn it", NULL);
return bad;
}
if (!Core::hook_em())
{
MessageBoxA(NULL, "Hooking failed!", "damn it", NULL);
return bad;
}
TFFI::initialize();
return good;
}

extern "C" __declspec(dllexport) const char* tffi_initialize(int n_args, const char* args)
{
if (!TFFI::initialize())
return bad;
return good;
}
5 changes: 3 additions & 2 deletions byond-extools/src/core/proc_management.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,12 @@ int Core::Proc::get_local_varcount()
return setup_entry_varcount->local_var_count;
}

Core::Proc get_proc(std::string name)
Core::Proc Core::get_proc(std::string name)
{
return procs_by_name[name];
}

Core::Proc get_proc(unsigned int id)
Core::Proc Core::get_proc(unsigned int id)
{
return procs_by_id[id];
}
Expand All @@ -72,4 +72,5 @@ bool Core::populate_proc_list()
procs_by_name[p.name] = p;
i++;
}
return true;
}
103 changes: 103 additions & 0 deletions byond-extools/src/dm/_extools_api.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#define EXTOOLS_SUCCESS "gucci"
#define EXTOOLS_FAILED "pain"

/*
Core - Provides necessary functionality for other modules.
Must be initialized first before initializing any modules!
*/

/proc/extools_initialize()
return call("byond-extools.dll", "core_initialize")() == EXTOOLS_SUCCESS

/*
TFFI - Threaded FFI
All DLL calls are automatically threaded off.
Black magic is used to suspend (sleep) the currently executing proc, allowing non-blocking FFI.
You may call a DLL function and sleep until it returns, pass a callback to be called with the result,
or call resolve() on the /datum/promise to receive the return value at any time.
Example:
var/x = call_wait("sample.dll", "do_work", "arg1", "arg2", "arg3")
- Calls the do_work function from sample.dll with 3 arguments. The proc sleeps until do_work returns.
var/datum/promise/P = call_async("sample.dll", "do_work", "arg1")
... do something else ...
var/result = P.resolve()
- Calls do_work with 1 argument. Returns a promise object. Runs some other code before calling P.resolve() to obtain the result.
/proc/print_result(result)
world << result
call_cb("sample.dll", "do_work", /proc/print_result, "arg1", "arg2")
- Calls do_work with 2 arguments. The callback is invoked with the result as the single argument. Execution resumes immediately.
*/

/proc/tffi_initialize()
call("byond-extools.dll", "tffi_initialize")() == EXTOOLS_SUCCESS

var/fallback_alerted = FALSE
var/next_promise_id = 0

/datum/promise
var/completed = FALSE
var/result = ""
var/cb = null
var/__id = 0

/datum/promise/New()
__id = next_promise_id++ //please don't create more than 10^38 promises in a single tick

//This proc's bytecode is overwritten to allow suspending and resuming on demand.
//None of the code here should run.
/datum/promise/proc/__internal_resolve(ref, id)
if(!fallback_alerted)
world << "<b>TFFI: __internal_resolve has not been rewritten, the TFFI DLL was not loaded correctly.</b>"
world.log << "<b>TFFI: __internal_resolve has not been rewritten, the TFFI DLL was not loaded correctly.</b>"
fallback_alerted = TRUE
while(!completed)
sleep(1)
//It might be better to just fail and notify the user that something went wrong.

/datum/promise/proc/__resolve_callback()
__internal_resolve("\ref[src]", __id)
call(cb)(result)

/datum/promise/proc/resolve()
__internal_resolve("\ref[src]", __id)
return result

/proc/call_async()
var/list/arguments = args.Copy()
var/datum/promise/P = new
arguments.Insert(1, "\ref[P]")
call("byond-extools.dll", "call_async")(arglist(arguments))
return P

/proc/call_cb()
var/list/arguments = args.Copy()
var/callback = arguments[3]
arguments.Cut(3, 4)
var/datum/promise/P = new
P.cb = callback
arguments.Insert(1, "\ref[P]")
call("byond-extools.dll", "call_async")(arglist(arguments))
spawn(0)
P.__resolve_callback()

/proc/call_wait()
return call_async(arglist(args)).resolve()

0 comments on commit 38ef248

Please sign in to comment.