mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-07 08:15:59 -10:00
Add scripting API for custom execution context
This allows a script to create its own execution context so that it can control when a coroutine is valid to play based on custom data. Also adds a function which causes a coroutine to end in an error.
This commit is contained in:
1 parent
b419d3fac5
commit
8fcb05bfd0
10 files changed
+447
-505
No files matched your search
@@ -0,0 +1,34 @@
|
||||
#include "CombinedExecutionContext.h"
|
||||
|
||||
namespace executor {
|
||||
CombinedExecutionContext::CombinedExecutionContext(SCP_vector<std::shared_ptr<IExecutionContext>> contexts)
|
||||
: m_contexts(std::move(contexts))
|
||||
{
|
||||
}
|
||||
IExecutionContext::State CombinedExecutionContext::determineContextState() const
|
||||
{
|
||||
bool suspended_context = false;
|
||||
bool invalid_context = false;
|
||||
for (const auto& context : m_contexts) {
|
||||
const auto state = context->determineContextState();
|
||||
|
||||
if (state == IExecutionContext::State::Suspended) {
|
||||
suspended_context = true;
|
||||
} else if (state == IExecutionContext::State::Invalid) {
|
||||
invalid_context = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If there is an invalid context then the combined state is invalid
|
||||
// If there is not but there is a suspended one, then the state is suspended
|
||||
if (invalid_context) {
|
||||
return IExecutionContext::State::Invalid;
|
||||
} else if (suspended_context) {
|
||||
return IExecutionContext::State::Suspended;
|
||||
} else {
|
||||
return IExecutionContext::State::Valid;
|
||||
}
|
||||
}
|
||||
CombinedExecutionContext::~CombinedExecutionContext() = default;
|
||||
|
||||
} // namespace executor
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include "IExecutionContext.h"
|
||||
|
||||
#include "gamesequence/gamesequence.h"
|
||||
#include "utils/event.h"
|
||||
|
||||
namespace executor {
|
||||
|
||||
class CombinedExecutionContext : public IExecutionContext {
|
||||
public:
|
||||
CombinedExecutionContext(SCP_vector<std::shared_ptr<IExecutionContext>> contexts);
|
||||
~CombinedExecutionContext() override;
|
||||
|
||||
State determineContextState() const override;
|
||||
|
||||
private:
|
||||
SCP_vector<std::shared_ptr<IExecutionContext>> m_contexts;
|
||||
};
|
||||
|
||||
} // namespace executor
|
||||
@@ -0,0 +1,50 @@
|
||||
#include "LuaExecutionContext.h"
|
||||
|
||||
#include "scripting/ade_args.h"
|
||||
#include "scripting/api/objs/enums.h"
|
||||
|
||||
namespace scripting {
|
||||
namespace api {
|
||||
|
||||
LuaExecutionContext::LuaExecutionContext(luacpp::LuaFunction contextFunction)
|
||||
: m_contextFunction(std::move(contextFunction))
|
||||
{
|
||||
}
|
||||
LuaExecutionContext::~LuaExecutionContext() = default;
|
||||
|
||||
executor::IExecutionContext::State LuaExecutionContext::determineContextState() const
|
||||
{
|
||||
auto L = m_contextFunction.getLuaState();
|
||||
const auto returnVal = m_contextFunction.call(L);
|
||||
if (returnVal.size() != 1) {
|
||||
LuaError(L, "Need exactly one return value for Lua execution context function!");
|
||||
return executor::IExecutionContext::State::Invalid;
|
||||
}
|
||||
|
||||
const auto currentTop = lua_gettop(L);
|
||||
returnVal[0].pushValue(L);
|
||||
|
||||
enum_h enumValue;
|
||||
internal::Ade_get_args_lfunction = true;
|
||||
internal::Ade_get_args_skip = currentTop;
|
||||
if (!ade_get_args(L, "o", l_Enum.Get(&enumValue))) {
|
||||
lua_settop(L, currentTop);
|
||||
return executor::IExecutionContext::State::Invalid;
|
||||
}
|
||||
lua_settop(L, currentTop);
|
||||
|
||||
switch (enumValue.index) {
|
||||
case LE_CONTEXT_INVALID:
|
||||
return executor::IExecutionContext::State::Invalid;
|
||||
case LE_CONTEXT_SUSPENDED:
|
||||
return executor::IExecutionContext::State::Suspended;
|
||||
case LE_CONTEXT_VALID:
|
||||
return executor::IExecutionContext::State::Valid;
|
||||
default:
|
||||
LuaError(L, "Got invalid enum value %s from Lua context function.", enumValue.getName().c_str());
|
||||
return executor::IExecutionContext::State::Invalid;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
} // namespace scripting
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "executor/IExecutionContext.h"
|
||||
#include "gamesequence/gamesequence.h"
|
||||
#include "scripting/lua/LuaFunction.h"
|
||||
#include "utils/event.h"
|
||||
|
||||
namespace scripting {
|
||||
namespace api {
|
||||
|
||||
class LuaExecutionContext : public executor::IExecutionContext {
|
||||
public:
|
||||
LuaExecutionContext(luacpp::LuaFunction contextFunction);
|
||||
~LuaExecutionContext() override;
|
||||
|
||||
State determineContextState() const override;
|
||||
|
||||
private:
|
||||
luacpp::LuaFunction m_contextFunction;
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
} // namespace scripting
|
||||
@@ -1,9 +1,12 @@
|
||||
|
||||
#include "async.h"
|
||||
|
||||
#include "executor/CombinedExecutionContext.h"
|
||||
#include "executor/GameStateExecutionContext.h"
|
||||
#include "executor/global_executors.h"
|
||||
#include "scripting/api/LuaCoroutineRunner.h"
|
||||
#include "scripting/api/LuaExecutionContext.h"
|
||||
#include "scripting/api/objs/execution_context.h"
|
||||
#include "scripting/api/objs/executor.h"
|
||||
#include "scripting/api/objs/promise.h"
|
||||
#include "scripting/lua/LuaThread.h"
|
||||
@@ -169,7 +172,8 @@ ADE_FUNC(errored,
|
||||
|
||||
ADE_FUNC(run,
|
||||
l_Async,
|
||||
"function() => any body",
|
||||
"function() => any body, [executor executeOn = nil, boolean|execution_context captureContext = true /* Captures "
|
||||
"game state context by default */]",
|
||||
"Runs an asynchronous function. Inside this function you can use async.await to suspend the function until a "
|
||||
"promise resolves.",
|
||||
"promise",
|
||||
@@ -177,9 +181,24 @@ ADE_FUNC(run,
|
||||
{
|
||||
luacpp::LuaFunction body;
|
||||
executor_h executor;
|
||||
bool captureContext = true;
|
||||
if (!ade_get_args(L, "u|ob", &body, l_Executor.Get(&executor), &captureContext)) {
|
||||
return ADE_RETURN_NIL;
|
||||
std::shared_ptr<executor::IExecutionContext> context;
|
||||
|
||||
if (lua_type(L, 3) == LUA_TUSERDATA) {
|
||||
execution_context_h* ctx = nullptr;
|
||||
if (!ade_get_args(L, "u|oo", &body, l_Executor.Get(&executor), l_ExecutionContext.GetPtr(&ctx))) {
|
||||
return ADE_RETURN_NIL;
|
||||
}
|
||||
if (ctx != nullptr) {
|
||||
context = ctx->getExecutionContext();
|
||||
}
|
||||
} else {
|
||||
bool captureContext = true;
|
||||
if (!ade_get_args(L, "u|ob", &body, l_Executor.Get(&executor), &captureContext)) {
|
||||
return ADE_RETURN_NIL;
|
||||
}
|
||||
if (executor.isValid() && captureContext) {
|
||||
context = executor::GameStateExecutionContext::captureContext();
|
||||
}
|
||||
}
|
||||
|
||||
auto coroutine = luacpp::LuaThread::create(L, body);
|
||||
@@ -188,14 +207,9 @@ ADE_FUNC(run,
|
||||
return true;
|
||||
});
|
||||
|
||||
std::shared_ptr<executor::IExecutionContext> exeContext;
|
||||
if (executor.isValid() && captureContext) {
|
||||
exeContext = executor::GameStateExecutionContext::captureContext();
|
||||
}
|
||||
|
||||
return ade_set_args(L,
|
||||
"o",
|
||||
l_Promise.Set(runAsyncCoroutine(std::move(coroutine), executor.getExecutor(), std::move(exeContext))));
|
||||
l_Promise.Set(runAsyncCoroutine(std::move(coroutine), executor.getExecutor(), std::move(context))));
|
||||
}
|
||||
|
||||
ADE_FUNC(await,
|
||||
@@ -273,5 +287,93 @@ ADE_FUNC(yield,
|
||||
l_Promise.Set(LuaPromise(std::make_shared<yield_resolve_context>(executor::currentExecutor()))));
|
||||
}
|
||||
|
||||
ADE_FUNC(error,
|
||||
l_Async,
|
||||
"...",
|
||||
"Causes the currently running coroutine to fail with an error with the specified values.",
|
||||
nullptr,
|
||||
"Does not return")
|
||||
{
|
||||
// error cannot be used on the main thread since there is nothing that will wait for the promise
|
||||
if (lua_pushthread(L)) {
|
||||
// We are the main thread
|
||||
lua_pop(L, 1);
|
||||
|
||||
LuaError(L, "Tried to cause a coroutine error on the main thread! That is not supported.");
|
||||
return ADE_RETURN_NIL;
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
auto nargs = lua_gettop(L);
|
||||
luacpp::LuaValueList values;
|
||||
values.reserve(nargs);
|
||||
|
||||
for (int i = 1; i <= nargs; ++i) {
|
||||
luacpp::LuaValue val;
|
||||
val.setReference(luacpp::UniqueLuaReference::create(L, i));
|
||||
values.push_back(val);
|
||||
}
|
||||
|
||||
// Push an errored promise on the stack and then yield the coroutine. The awaiter will get this promise and stop
|
||||
// execution.
|
||||
ade_set_args(L, "o", l_Promise.Set(LuaPromise::errored(values)));
|
||||
return lua_yield(L, 1);
|
||||
}
|
||||
|
||||
//**********SUBLIBRARY: async/context
|
||||
ADE_LIB_DERIV(l_Async_Context, "context", nullptr, "Support library for creating execution contexts.", l_Async);
|
||||
|
||||
ADE_FUNC(captureGameState,
|
||||
l_Async_Context,
|
||||
nullptr,
|
||||
"Captures the current game state as an execution context",
|
||||
"execution_context",
|
||||
"The execution context or invalid handle on error")
|
||||
{
|
||||
return ade_set_args(L,
|
||||
"o",
|
||||
l_ExecutionContext.Set(execution_context_h(executor::GameStateExecutionContext::captureContext())));
|
||||
}
|
||||
|
||||
ADE_FUNC(createLuaState,
|
||||
l_Async_Context,
|
||||
"function() => enumeration",
|
||||
"Creates an execution state by storing the passed function and calling that when the state is required.",
|
||||
"execution_context",
|
||||
"The execution context or invalid handle on error")
|
||||
{
|
||||
luacpp::LuaFunction body;
|
||||
if (!ade_get_args(L, "u", &body)) {
|
||||
return ade_set_args(L, "o", l_ExecutionContext.Set(execution_context_h(nullptr)));
|
||||
}
|
||||
|
||||
return ade_set_args(L,
|
||||
"o",
|
||||
l_ExecutionContext.Set(execution_context_h(std::make_shared<LuaExecutionContext>(std::move(body)))));
|
||||
}
|
||||
|
||||
ADE_FUNC(combineContexts,
|
||||
l_Async_Context,
|
||||
"execution_context... contexts",
|
||||
"Combines several execution contexts into a single one by only return a valid state if all contexts are valid.",
|
||||
"execution_context",
|
||||
"The execution context or invalid handle on error")
|
||||
{
|
||||
SCP_vector<std::shared_ptr<executor::IExecutionContext>> contexts;
|
||||
for (int i = 0; i < lua_gettop(L); ++i) {
|
||||
execution_context_h* ctx;
|
||||
internal::Ade_get_args_skip = i;
|
||||
if (!ade_get_args(L, "o", l_ExecutionContext.GetPtr(&ctx))) {
|
||||
return ade_set_args(L, "o", l_ExecutionContext.Set(execution_context_h(nullptr)));
|
||||
}
|
||||
contexts.emplace_back(ctx->getExecutionContext());
|
||||
}
|
||||
|
||||
return ade_set_args(L,
|
||||
"o",
|
||||
l_ExecutionContext.Set(
|
||||
execution_context_h(std::make_shared<executor::CombinedExecutionContext>(std::move(contexts)))));
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
} // namespace scripting
|
||||
+103
-494
@@ -13,494 +13,95 @@ namespace api {
|
||||
//or after. Don't forget to increment NEXT INDEX after you're done.
|
||||
//=====================================
|
||||
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
// clang-format off
|
||||
flag_def_list Enumerations[] = {
|
||||
{
|
||||
"ALPHABLEND_FILTER",
|
||||
LE_ALPHABLEND_FILTER,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"ALPHABLEND_NONE",
|
||||
LE_ALPHABLEND_NONE,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"CFILE_TYPE_NORMAL",
|
||||
LE_CFILE_TYPE_NORMAL,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"CFILE_TYPE_MEMORY_MAPPED",
|
||||
LE_CFILE_TYPE_MEMORY_MAPPED,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"MOUSE_LEFT_BUTTON",
|
||||
LE_MOUSE_LEFT_BUTTON,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"MOUSE_RIGHT_BUTTON",
|
||||
LE_MOUSE_RIGHT_BUTTON,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"MOUSE_MIDDLE_BUTTON",
|
||||
LE_MOUSE_MIDDLE_BUTTON,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"ORDER_ATTACK",
|
||||
LE_ORDER_ATTACK,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"ORDER_ATTACK_ANY",
|
||||
LE_ORDER_ATTACK_ANY,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"ORDER_DEPART",
|
||||
LE_ORDER_DEPART,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"ORDER_DISABLE",
|
||||
LE_ORDER_DISABLE,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"ORDER_DISARM",
|
||||
LE_ORDER_DISARM,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"ORDER_DOCK",
|
||||
LE_ORDER_DOCK,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"ORDER_EVADE",
|
||||
LE_ORDER_EVADE,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"ORDER_FLY_TO",
|
||||
LE_ORDER_FLY_TO,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"ORDER_FORM_ON_WING",
|
||||
LE_ORDER_FORM_ON_WING,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"ORDER_GUARD",
|
||||
LE_ORDER_GUARD,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"ORDER_IGNORE_SHIP",
|
||||
LE_ORDER_IGNORE,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"ORDER_KEEP_SAFE_DISTANCE",
|
||||
LE_ORDER_KEEP_SAFE_DISTANCE,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"ORDER_PLAY_DEAD",
|
||||
LE_ORDER_PLAY_DEAD,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"ORDER_PLAY_DEAD_PERSISTENT",
|
||||
LE_ORDER_PLAY_DEAD_PERSISTENT,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"ORDER_REARM",
|
||||
LE_ORDER_REARM,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"ORDER_STAY_NEAR",
|
||||
LE_ORDER_STAY_NEAR,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"ORDER_STAY_STILL",
|
||||
LE_ORDER_STAY_STILL,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"ORDER_UNDOCK",
|
||||
LE_ORDER_UNDOCK,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"ORDER_WAYPOINTS",
|
||||
LE_ORDER_WAYPOINTS,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"ORDER_WAYPOINTS_ONCE",
|
||||
LE_ORDER_WAYPOINTS_ONCE,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"ORDER_ATTACK_WING",
|
||||
LE_ORDER_ATTACK_WING,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"ORDER_GUARD_WING",
|
||||
LE_ORDER_GUARD_WING,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"ORDER_ATTACK_SHIP_CLASS",
|
||||
LE_ORDER_ATTACK_SHIP_CLASS,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"PARTICLE_DEBUG",
|
||||
LE_PARTICLE_DEBUG,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"PARTICLE_BITMAP",
|
||||
LE_PARTICLE_BITMAP,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"PARTICLE_FIRE",
|
||||
LE_PARTICLE_FIRE,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"PARTICLE_SMOKE",
|
||||
LE_PARTICLE_SMOKE,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"PARTICLE_SMOKE2",
|
||||
LE_PARTICLE_SMOKE2,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"PARTICLE_PERSISTENT_BITMAP",
|
||||
LE_PARTICLE_PERSISTENT_BITMAP,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"SEXPVAR_CAMPAIGN_PERSISTENT",
|
||||
LE_SEXPVAR_CAMPAIGN_PERSISTENT,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"SEXPVAR_NOT_PERSISTENT",
|
||||
LE_SEXPVAR_NOT_PERSISTENT,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"SEXPVAR_PLAYER_PERSISTENT",
|
||||
LE_SEXPVAR_PLAYER_PERSISTENT,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"SEXPVAR_TYPE_NUMBER",
|
||||
LE_SEXPVAR_TYPE_NUMBER,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"SEXPVAR_TYPE_STRING",
|
||||
LE_SEXPVAR_TYPE_STRING,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"TEXTURE_STATIC",
|
||||
LE_TEXTURE_STATIC,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"TEXTURE_DYNAMIC",
|
||||
LE_TEXTURE_DYNAMIC,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"LOCK",
|
||||
LE_LOCK,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"UNLOCK",
|
||||
LE_UNLOCK,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"NONE",
|
||||
LE_NONE,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"SHIELD_FRONT",
|
||||
LE_SHIELD_FRONT,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"SHIELD_LEFT",
|
||||
LE_SHIELD_LEFT,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"SHIELD_RIGHT",
|
||||
LE_SHIELD_RIGHT,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"SHIELD_BACK",
|
||||
LE_SHIELD_BACK,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"MISSION_REPEAT",
|
||||
LE_MISSION_REPEAT,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"NORMAL_CONTROLS",
|
||||
LE_NORMAL_CONTROLS,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"LUA_STEERING_CONTROLS",
|
||||
LE_LUA_STEERING_CONTROLS,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"LUA_FULL_CONTROLS",
|
||||
LE_LUA_FULL_CONTROLS,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"NORMAL_BUTTON_CONTROLS",
|
||||
LE_NORMAL_BUTTON_CONTROLS,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"LUA_ADDITIVE_BUTTON_CONTROL",
|
||||
LE_LUA_ADDITIVE_BUTTON_CONTROL,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"LUA_OVERRIDE_BUTTON_CONTROL",
|
||||
LE_LUA_OVERRIDE_BUTTON_CONTROL,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"VM_INTERNAL",
|
||||
LE_VM_INTERNAL,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"VM_EXTERNAL",
|
||||
LE_VM_EXTERNAL,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"VM_TRACK",
|
||||
LE_VM_TRACK,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"VM_DEAD_VIEW",
|
||||
LE_VM_DEAD_VIEW,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"VM_CHASE",
|
||||
LE_VM_CHASE,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"VM_OTHER_SHIP",
|
||||
LE_VM_OTHER_SHIP,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"VM_EXTERNAL_CAMERA_LOCKED",
|
||||
LE_VM_EXTERNAL_CAMERA_LOCKED,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"VM_CAMERA_LOCKED",
|
||||
LE_VM_CAMERA_LOCKED,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"VM_WARP_CHASE",
|
||||
LE_VM_WARP_CHASE,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"VM_PADLOCK_UP",
|
||||
LE_VM_PADLOCK_UP,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"VM_PADLOCK_REAR",
|
||||
LE_VM_PADLOCK_REAR,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"VM_PADLOCK_LEFT",
|
||||
LE_VM_PADLOCK_LEFT,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"VM_PADLOCK_RIGHT",
|
||||
LE_VM_PADLOCK_RIGHT,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"VM_WARPIN_ANCHOR",
|
||||
LE_VM_WARPIN_ANCHOR,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"VM_TOPDOWN",
|
||||
LE_VM_TOPDOWN,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"VM_FREECAMERA",
|
||||
LE_VM_FREECAMERA,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"VM_CENTERING",
|
||||
LE_VM_CENTERING,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"MESSAGE_PRIORITY_LOW",
|
||||
LE_MESSAGE_PRIORITY_LOW,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"MESSAGE_PRIORITY_NORMAL",
|
||||
LE_MESSAGE_PRIORITY_NORMAL,
|
||||
0
|
||||
},
|
||||
|
||||
{
|
||||
"MESSAGE_PRIORITY_HIGH",
|
||||
LE_MESSAGE_PRIORITY_HIGH,
|
||||
0
|
||||
},
|
||||
{
|
||||
"OPTION_TYPE_SELECTION",
|
||||
LE_OPTION_TYPE_SELECTION,
|
||||
0
|
||||
},
|
||||
{
|
||||
"OPTION_TYPE_RANGE",
|
||||
LE_OPTION_TYPE_RANGE,
|
||||
0
|
||||
},
|
||||
{
|
||||
"AUDIOSTREAM_EVENTMUSIC",
|
||||
LE_ASF_EVENTMUSIC,
|
||||
0
|
||||
},
|
||||
{
|
||||
"AUDIOSTREAM_MENUMUSIC",
|
||||
LE_ASF_MENUMUSIC,
|
||||
0
|
||||
},
|
||||
{
|
||||
"AUDIOSTREAM_VOICE",
|
||||
LE_ASF_VOICE,
|
||||
0
|
||||
},
|
||||
{"ALPHABLEND_FILTER", LE_ALPHABLEND_FILTER, 0},
|
||||
{"ALPHABLEND_NONE", LE_ALPHABLEND_NONE, 0},
|
||||
{"CFILE_TYPE_NORMAL", LE_CFILE_TYPE_NORMAL, 0},
|
||||
{"CFILE_TYPE_MEMORY_MAPPED", LE_CFILE_TYPE_MEMORY_MAPPED, 0},
|
||||
{"MOUSE_LEFT_BUTTON", LE_MOUSE_LEFT_BUTTON, 0},
|
||||
{"MOUSE_RIGHT_BUTTON", LE_MOUSE_RIGHT_BUTTON, 0},
|
||||
{"MOUSE_MIDDLE_BUTTON", LE_MOUSE_MIDDLE_BUTTON, 0},
|
||||
{"ORDER_ATTACK", LE_ORDER_ATTACK, 0},
|
||||
{"ORDER_ATTACK_ANY", LE_ORDER_ATTACK_ANY, 0},
|
||||
{"ORDER_DEPART", LE_ORDER_DEPART, 0},
|
||||
{"ORDER_DISABLE", LE_ORDER_DISABLE, 0},
|
||||
{"ORDER_DISARM", LE_ORDER_DISARM, 0},
|
||||
{"ORDER_DOCK", LE_ORDER_DOCK, 0},
|
||||
{"ORDER_EVADE", LE_ORDER_EVADE, 0},
|
||||
{"ORDER_FLY_TO", LE_ORDER_FLY_TO, 0},
|
||||
{"ORDER_FORM_ON_WING", LE_ORDER_FORM_ON_WING, 0},
|
||||
{"ORDER_GUARD", LE_ORDER_GUARD, 0},
|
||||
{"ORDER_IGNORE_SHIP", LE_ORDER_IGNORE, 0},
|
||||
{"ORDER_KEEP_SAFE_DISTANCE", LE_ORDER_KEEP_SAFE_DISTANCE, 0},
|
||||
{"ORDER_PLAY_DEAD", LE_ORDER_PLAY_DEAD, 0},
|
||||
{"ORDER_PLAY_DEAD_PERSISTENT", LE_ORDER_PLAY_DEAD_PERSISTENT, 0},
|
||||
{"ORDER_REARM", LE_ORDER_REARM, 0},
|
||||
{"ORDER_STAY_NEAR", LE_ORDER_STAY_NEAR, 0},
|
||||
{"ORDER_STAY_STILL", LE_ORDER_STAY_STILL, 0},
|
||||
{"ORDER_UNDOCK", LE_ORDER_UNDOCK, 0},
|
||||
{"ORDER_WAYPOINTS", LE_ORDER_WAYPOINTS, 0},
|
||||
{"ORDER_WAYPOINTS_ONCE", LE_ORDER_WAYPOINTS_ONCE, 0},
|
||||
{"ORDER_ATTACK_WING", LE_ORDER_ATTACK_WING, 0},
|
||||
{"ORDER_GUARD_WING", LE_ORDER_GUARD_WING, 0},
|
||||
{"ORDER_ATTACK_SHIP_CLASS", LE_ORDER_ATTACK_SHIP_CLASS, 0},
|
||||
{"PARTICLE_DEBUG", LE_PARTICLE_DEBUG, 0},
|
||||
{"PARTICLE_BITMAP", LE_PARTICLE_BITMAP, 0},
|
||||
{"PARTICLE_FIRE", LE_PARTICLE_FIRE, 0},
|
||||
{"PARTICLE_SMOKE", LE_PARTICLE_SMOKE, 0},
|
||||
{"PARTICLE_SMOKE2", LE_PARTICLE_SMOKE2, 0},
|
||||
{"PARTICLE_PERSISTENT_BITMAP", LE_PARTICLE_PERSISTENT_BITMAP, 0},
|
||||
{"SEXPVAR_CAMPAIGN_PERSISTENT", LE_SEXPVAR_CAMPAIGN_PERSISTENT, 0},
|
||||
{"SEXPVAR_NOT_PERSISTENT", LE_SEXPVAR_NOT_PERSISTENT, 0},
|
||||
{"SEXPVAR_PLAYER_PERSISTENT", LE_SEXPVAR_PLAYER_PERSISTENT, 0},
|
||||
{"SEXPVAR_TYPE_NUMBER", LE_SEXPVAR_TYPE_NUMBER, 0},
|
||||
{"SEXPVAR_TYPE_STRING", LE_SEXPVAR_TYPE_STRING, 0},
|
||||
{"TEXTURE_STATIC", LE_TEXTURE_STATIC, 0},
|
||||
{"TEXTURE_DYNAMIC", LE_TEXTURE_DYNAMIC, 0},
|
||||
{"LOCK", LE_LOCK, 0},
|
||||
{"UNLOCK", LE_UNLOCK, 0},
|
||||
{"NONE", LE_NONE, 0},
|
||||
{"SHIELD_FRONT", LE_SHIELD_FRONT, 0},
|
||||
{"SHIELD_LEFT", LE_SHIELD_LEFT, 0},
|
||||
{"SHIELD_RIGHT", LE_SHIELD_RIGHT, 0},
|
||||
{"SHIELD_BACK", LE_SHIELD_BACK, 0},
|
||||
{"MISSION_REPEAT", LE_MISSION_REPEAT, 0},
|
||||
{"NORMAL_CONTROLS", LE_NORMAL_CONTROLS, 0},
|
||||
{"LUA_STEERING_CONTROLS", LE_LUA_STEERING_CONTROLS, 0},
|
||||
{"LUA_FULL_CONTROLS", LE_LUA_FULL_CONTROLS, 0},
|
||||
{"NORMAL_BUTTON_CONTROLS", LE_NORMAL_BUTTON_CONTROLS, 0},
|
||||
{"LUA_ADDITIVE_BUTTON_CONTROL", LE_LUA_ADDITIVE_BUTTON_CONTROL, 0},
|
||||
{"LUA_OVERRIDE_BUTTON_CONTROL", LE_LUA_OVERRIDE_BUTTON_CONTROL, 0},
|
||||
{"VM_INTERNAL", LE_VM_INTERNAL, 0},
|
||||
{"VM_EXTERNAL", LE_VM_EXTERNAL, 0},
|
||||
{"VM_TRACK", LE_VM_TRACK, 0},
|
||||
{"VM_DEAD_VIEW", LE_VM_DEAD_VIEW, 0},
|
||||
{"VM_CHASE", LE_VM_CHASE, 0},
|
||||
{"VM_OTHER_SHIP", LE_VM_OTHER_SHIP, 0},
|
||||
{"VM_EXTERNAL_CAMERA_LOCKED", LE_VM_EXTERNAL_CAMERA_LOCKED, 0},
|
||||
{"VM_CAMERA_LOCKED", LE_VM_CAMERA_LOCKED, 0},
|
||||
{"VM_WARP_CHASE", LE_VM_WARP_CHASE, 0},
|
||||
{"VM_PADLOCK_UP", LE_VM_PADLOCK_UP, 0},
|
||||
{"VM_PADLOCK_REAR", LE_VM_PADLOCK_REAR, 0},
|
||||
{"VM_PADLOCK_LEFT", LE_VM_PADLOCK_LEFT, 0},
|
||||
{"VM_PADLOCK_RIGHT", LE_VM_PADLOCK_RIGHT, 0},
|
||||
{"VM_WARPIN_ANCHOR", LE_VM_WARPIN_ANCHOR, 0},
|
||||
{"VM_TOPDOWN", LE_VM_TOPDOWN, 0},
|
||||
{"VM_FREECAMERA", LE_VM_FREECAMERA, 0},
|
||||
{"VM_CENTERING", LE_VM_CENTERING, 0},
|
||||
{"MESSAGE_PRIORITY_LOW", LE_MESSAGE_PRIORITY_LOW, 0},
|
||||
{"MESSAGE_PRIORITY_NORMAL", LE_MESSAGE_PRIORITY_NORMAL, 0},
|
||||
{"MESSAGE_PRIORITY_HIGH", LE_MESSAGE_PRIORITY_HIGH, 0},
|
||||
{"OPTION_TYPE_SELECTION", LE_OPTION_TYPE_SELECTION, 0},
|
||||
{"OPTION_TYPE_RANGE", LE_OPTION_TYPE_RANGE, 0},
|
||||
{"AUDIOSTREAM_EVENTMUSIC", LE_ASF_EVENTMUSIC, 0},
|
||||
{"AUDIOSTREAM_MENUMUSIC", LE_ASF_MENUMUSIC, 0},
|
||||
{"AUDIOSTREAM_VOICE", LE_ASF_VOICE, 0},
|
||||
{"CONTEXT_VALID", LE_CONTEXT_VALID, 0},
|
||||
{"CONTEXT_SUSPENDED", LE_CONTEXT_SUSPENDED, 0},
|
||||
{"CONTEXT_INVALID", LE_CONTEXT_INVALID, 0},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
//DO NOT FORGET to increment NEXT INDEX: !!!!!!!!!!!!!
|
||||
|
||||
@@ -511,10 +112,21 @@ enum_h::enum_h() {
|
||||
index = -1;
|
||||
is_constant = false;
|
||||
}
|
||||
enum_h::enum_h(int n_index) {
|
||||
enum_h::enum_h(int n_index)
|
||||
{
|
||||
index = n_index;
|
||||
is_constant = false;
|
||||
}
|
||||
SCP_string enum_h::getName() const
|
||||
{
|
||||
for (size_t i = 0; i < Num_enumerations; i++) {
|
||||
if (Enumerations[i].def == index) {
|
||||
return Enumerations[i].name;
|
||||
}
|
||||
}
|
||||
|
||||
return SCP_string();
|
||||
}
|
||||
bool enum_h::IsValid() const { return (index > -1 && index < ENUM_NEXT_INDEX); }
|
||||
|
||||
ADE_OBJ(l_Enum, enum_h, "enumeration", "Enumeration object");
|
||||
@@ -552,14 +164,11 @@ ADE_FUNC(__tostring,
|
||||
return ade_set_args(L, "s", "<INVALID>");
|
||||
}
|
||||
|
||||
uint i;
|
||||
for (i = 0; i < Num_enumerations; i++) {
|
||||
if (Enumerations[i].def == e->index) {
|
||||
return ade_set_args(L, "s", Enumerations[i].name);
|
||||
}
|
||||
const auto name = e->getName();
|
||||
if (name.empty()) {
|
||||
return ade_set_args(L, "s", "<INVALID>");
|
||||
}
|
||||
|
||||
return ade_set_args(L, "s", "<INVALID>");
|
||||
return ade_set_args(L, "s", name);
|
||||
}
|
||||
|
||||
ADE_FUNC(__eq,
|
||||
|
||||
@@ -92,8 +92,11 @@ const int32_t LE_OPTION_TYPE_RANGE = 79;
|
||||
const int32_t LE_ASF_EVENTMUSIC = 80;
|
||||
const int32_t LE_ASF_MENUMUSIC = 81;
|
||||
const int32_t LE_ASF_VOICE = 82;
|
||||
const int32_t LE_CONTEXT_VALID = 83;
|
||||
const int32_t LE_CONTEXT_SUSPENDED = 84;
|
||||
const int32_t LE_CONTEXT_INVALID = 85;
|
||||
|
||||
const int ENUM_NEXT_INDEX = 83; // <<<<<<<<<<<<<<<<<<<<<<
|
||||
const int ENUM_NEXT_INDEX = 86; // <<<<<<<<<<<<<<<<<<<<<<
|
||||
extern flag_def_list Enumerations[];
|
||||
extern size_t Num_enumerations;
|
||||
|
||||
@@ -105,6 +108,8 @@ struct enum_h {
|
||||
|
||||
explicit enum_h(int n_index);
|
||||
|
||||
SCP_string getName() const;
|
||||
|
||||
bool IsValid() const;
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
#include "execution_context.h"
|
||||
|
||||
#include "enums.h"
|
||||
|
||||
namespace scripting {
|
||||
namespace api {
|
||||
|
||||
execution_context_h::execution_context_h(std::shared_ptr<executor::IExecutionContext> executionContext)
|
||||
: m_executionContext(std::move(executionContext))
|
||||
{
|
||||
}
|
||||
const std::shared_ptr<executor::IExecutionContext>& execution_context_h::getExecutionContext() const
|
||||
{
|
||||
return m_executionContext;
|
||||
}
|
||||
bool execution_context_h::isValid() const { return m_executionContext != nullptr; }
|
||||
|
||||
ADE_OBJ(l_ExecutionContext,
|
||||
execution_context_h,
|
||||
"execution_context",
|
||||
"An execution context for asynchonous operations");
|
||||
|
||||
ADE_FUNC(determineState,
|
||||
l_ExecutionContext,
|
||||
nullptr,
|
||||
"Determines the current state of the context.",
|
||||
"enum",
|
||||
"One of the CONTEXT_ enumerations")
|
||||
{
|
||||
execution_context_h* context = nullptr;
|
||||
if (!ade_get_args(L, "o", l_ExecutionContext.GetPtr(&context))) {
|
||||
return ADE_RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (!context->isValid()) {
|
||||
return ade_set_args(L, "o", l_Enum.Set(enum_h(LE_CONTEXT_INVALID)));
|
||||
}
|
||||
|
||||
const auto state = context->getExecutionContext()->determineContextState();
|
||||
switch (state) {
|
||||
case executor::IExecutionContext::State::Valid:
|
||||
return ade_set_args(L, "o", l_Enum.Set(enum_h(LE_CONTEXT_VALID)));
|
||||
case executor::IExecutionContext::State::Suspended:
|
||||
return ade_set_args(L, "o", l_Enum.Set(enum_h(LE_CONTEXT_SUSPENDED)));
|
||||
case executor::IExecutionContext::State::Invalid:
|
||||
default:
|
||||
return ade_set_args(L, "o", l_Enum.Set(enum_h(LE_CONTEXT_INVALID)));
|
||||
}
|
||||
}
|
||||
|
||||
ADE_FUNC(isValid,
|
||||
l_ExecutionContext,
|
||||
nullptr,
|
||||
"Determines if the handle is valid",
|
||||
"boolean",
|
||||
"true if valid, false otherwise")
|
||||
{
|
||||
execution_context_h* context = nullptr;
|
||||
if (!ade_get_args(L, "o", l_ExecutionContext.GetPtr(&context))) {
|
||||
return ADE_RETURN_FALSE;
|
||||
}
|
||||
|
||||
return ade_set_args(L, "b", context != nullptr && context->isValid());
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
} // namespace scripting
|
||||
@@ -0,0 +1,25 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "executor/IExecutionContext.h"
|
||||
#include "scripting/ade_api.h"
|
||||
|
||||
namespace scripting {
|
||||
namespace api {
|
||||
|
||||
class execution_context_h {
|
||||
public:
|
||||
execution_context_h(std::shared_ptr<executor::IExecutionContext> executionContext);
|
||||
|
||||
const std::shared_ptr<executor::IExecutionContext>& getExecutionContext() const;
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
private:
|
||||
std::shared_ptr<executor::IExecutionContext> m_executionContext;
|
||||
};
|
||||
|
||||
DECLARE_ADE_OBJ(l_ExecutionContext, execution_context_h);
|
||||
|
||||
} // namespace api
|
||||
} // namespace scripting
|
||||
@@ -262,6 +262,8 @@ add_file_folder("ExceptionHandler"
|
||||
|
||||
# Executor files
|
||||
add_file_folder("Executor"
|
||||
executor/CombinedExecutionContext.cpp
|
||||
executor/CombinedExecutionContext.h
|
||||
executor/Executor.cpp
|
||||
executor/Executor.h
|
||||
executor/GameStateExecutionContext.cpp
|
||||
@@ -1091,6 +1093,8 @@ add_file_folder("Scripting\\\\Api"
|
||||
scripting/api/LuaCoroutineRunner.h
|
||||
scripting/api/LuaEventCallback.cpp
|
||||
scripting/api/LuaEventCallback.h
|
||||
scripting/api/LuaExecutionContext.cpp
|
||||
scripting/api/LuaExecutionContext.h
|
||||
scripting/api/LuaPromise.cpp
|
||||
scripting/api/LuaPromise.h
|
||||
)
|
||||
@@ -1157,6 +1161,8 @@ add_file_folder("Scripting\\\\Api\\\\Objs"
|
||||
scripting/api/objs/enums.h
|
||||
scripting/api/objs/event.cpp
|
||||
scripting/api/objs/event.h
|
||||
scripting/api/objs/execution_context.cpp
|
||||
scripting/api/objs/execution_context.h
|
||||
scripting/api/objs/executor.cpp
|
||||
scripting/api/objs/executor.h
|
||||
scripting/api/objs/eye.cpp
|
||||
|
||||
Reference in new issue
Block a user