Scripting: Split console implementation out from Core scripting

This commit is contained in:
Vicki Pfau 2024-06-09 01:12:14 -07:00
parent 59f4fb7132
commit 6f261f6f1b
6 changed files with 144 additions and 160 deletions

View File

@ -20,8 +20,6 @@ struct mCore;
struct mScriptTextBuffer; struct mScriptTextBuffer;
mSCRIPT_DECLARE_STRUCT(mCore); mSCRIPT_DECLARE_STRUCT(mCore);
mSCRIPT_DECLARE_STRUCT(mLogger); mSCRIPT_DECLARE_STRUCT(mLogger);
mSCRIPT_DECLARE_STRUCT(mScriptConsole);
mSCRIPT_DECLARE_STRUCT(mScriptTextBuffer);
struct mScriptBridge; struct mScriptBridge;
struct VFile; struct VFile;
@ -40,24 +38,6 @@ struct mScriptEngine {
#endif #endif
}; };
struct mScriptTextBuffer {
void (*init)(struct mScriptTextBuffer*, const char* name);
void (*deinit)(struct mScriptTextBuffer*);
void (*setName)(struct mScriptTextBuffer*, const char* text);
uint32_t (*getX)(const struct mScriptTextBuffer*);
uint32_t (*getY)(const struct mScriptTextBuffer*);
uint32_t (*cols)(const struct mScriptTextBuffer*);
uint32_t (*rows)(const struct mScriptTextBuffer*);
void (*print)(struct mScriptTextBuffer*, const char* text);
void (*clear)(struct mScriptTextBuffer*);
void (*setSize)(struct mScriptTextBuffer*, uint32_t cols, uint32_t rows);
void (*moveCursor)(struct mScriptTextBuffer*, uint32_t x, uint32_t y);
void (*advance)(struct mScriptTextBuffer*, int32_t);
};
struct mScriptBridge* mScriptBridgeCreate(void); struct mScriptBridge* mScriptBridgeCreate(void);
void mScriptBridgeDestroy(struct mScriptBridge*); void mScriptBridgeDestroy(struct mScriptBridge*);
@ -80,13 +60,6 @@ struct mScriptContext;
void mScriptContextAttachCore(struct mScriptContext*, struct mCore*); void mScriptContextAttachCore(struct mScriptContext*, struct mCore*);
void mScriptContextDetachCore(struct mScriptContext*); void mScriptContextDetachCore(struct mScriptContext*);
struct mLogger;
void mScriptContextAttachLogger(struct mScriptContext*, struct mLogger*);
void mScriptContextDetachLogger(struct mScriptContext*);
typedef struct mScriptTextBuffer* (*mScriptContextBufferFactory)(void*);
void mScriptContextSetTextBufferFactory(struct mScriptContext*, mScriptContextBufferFactory factory, void* cbContext);
CXX_GUARD_END CXX_GUARD_END
#endif #endif

View File

@ -8,6 +8,7 @@
#include <mgba/script/base.h> #include <mgba/script/base.h>
#include <mgba/script/canvas.h> #include <mgba/script/canvas.h>
#include <mgba/script/console.h>
#include <mgba/script/context.h> #include <mgba/script/context.h>
#include <mgba/script/input.h> #include <mgba/script/input.h>
#include <mgba/script/macros.h> #include <mgba/script/macros.h>

View File

@ -207,12 +207,6 @@ struct mScriptCoreAdapter {
#endif #endif
}; };
struct mScriptConsole {
struct mLogger* logger;
mScriptContextBufferFactory textBufferFactory;
void* textBufferContext;
};
#define CALCULATE_SEGMENT_INFO \ #define CALCULATE_SEGMENT_INFO \
uint32_t segmentSize = adapter->block.end - adapter->block.start; \ uint32_t segmentSize = adapter->block.end - adapter->block.start; \
uint32_t segmentStart = adapter->block.segmentStart - adapter->block.start; \ uint32_t segmentStart = adapter->block.segmentStart - adapter->block.start; \
@ -1354,130 +1348,3 @@ void mScriptContextDetachCore(struct mScriptContext* context) {
mScriptContextRemoveGlobal(context, "emu"); mScriptContextRemoveGlobal(context, "emu");
} }
static struct mScriptTextBuffer* _mScriptConsoleCreateBuffer(struct mScriptConsole* lib, const char* name) {
struct mScriptTextBuffer* buffer = lib->textBufferFactory(lib->textBufferContext);
buffer->init(buffer, name);
return buffer;
}
static void mScriptConsoleLog(struct mScriptConsole* console, const char* msg) {
if (console->logger) {
mLogExplicit(console->logger, _mLOG_CAT_SCRIPT, mLOG_INFO, "%s", msg);
} else {
mLog(_mLOG_CAT_SCRIPT, mLOG_INFO, "%s", msg);
}
}
static void mScriptConsoleWarn(struct mScriptConsole* console, const char* msg) {
if (console->logger) {
mLogExplicit(console->logger, _mLOG_CAT_SCRIPT, mLOG_WARN, "%s", msg);
} else {
mLog(_mLOG_CAT_SCRIPT, mLOG_WARN, "%s", msg);
}
}
static void mScriptConsoleError(struct mScriptConsole* console, const char* msg) {
if (console->logger) {
mLogExplicit(console->logger, _mLOG_CAT_SCRIPT, mLOG_ERROR, "%s", msg);
} else {
mLog(_mLOG_CAT_SCRIPT, mLOG_ERROR, "%s", msg);
}
}
mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptConsole, log, mScriptConsoleLog, 1, CHARP, msg);
mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptConsole, warn, mScriptConsoleWarn, 1, CHARP, msg);
mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptConsole, error, mScriptConsoleError, 1, CHARP, msg);
mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mScriptConsole, S(mScriptTextBuffer), createBuffer, _mScriptConsoleCreateBuffer, 1, CHARP, name);
mSCRIPT_DEFINE_STRUCT(mScriptConsole)
mSCRIPT_DEFINE_CLASS_DOCSTRING(
"A global singleton object `console` that can be used for presenting textual information to the user via a console."
)
mSCRIPT_DEFINE_DOCSTRING("Print a log to the console")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptConsole, log)
mSCRIPT_DEFINE_DOCSTRING("Print a warning to the console")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptConsole, warn)
mSCRIPT_DEFINE_DOCSTRING("Print an error to the console")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptConsole, error)
mSCRIPT_DEFINE_DOCSTRING("Create a text buffer that can be used to display custom information")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptConsole, createBuffer)
mSCRIPT_DEFINE_END;
mSCRIPT_DEFINE_STRUCT_BINDING_DEFAULTS(mScriptConsole, createBuffer)
mSCRIPT_CHARP(NULL)
mSCRIPT_DEFINE_DEFAULTS_END;
static struct mScriptConsole* _ensureConsole(struct mScriptContext* context) {
struct mScriptValue* value = mScriptContextGetGlobal(context, "console");
if (value) {
return value->value.opaque;
}
struct mScriptConsole* console = calloc(1, sizeof(*console));
value = mScriptValueAlloc(mSCRIPT_TYPE_MS_S(mScriptConsole));
value->value.opaque = console;
value->flags = mSCRIPT_VALUE_FLAG_FREE_BUFFER;
mScriptContextSetGlobal(context, "console", value);
mScriptContextSetDocstring(context, "console", "Singleton instance of struct::mScriptConsole");
return console;
}
void mScriptContextAttachLogger(struct mScriptContext* context, struct mLogger* logger) {
struct mScriptConsole* console = _ensureConsole(context);
console->logger = logger;
}
void mScriptContextDetachLogger(struct mScriptContext* context) {
struct mScriptValue* value = mScriptContextGetGlobal(context, "console");
if (!value) {
return;
}
struct mScriptConsole* console = value->value.opaque;
console->logger = mLogGetContext();
}
mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, deinit, 0);
mSCRIPT_DECLARE_STRUCT_CD_METHOD(mScriptTextBuffer, U32, getX, 0);
mSCRIPT_DECLARE_STRUCT_CD_METHOD(mScriptTextBuffer, U32, getY, 0);
mSCRIPT_DECLARE_STRUCT_CD_METHOD(mScriptTextBuffer, U32, cols, 0);
mSCRIPT_DECLARE_STRUCT_CD_METHOD(mScriptTextBuffer, U32, rows, 0);
mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, print, 1, CHARP, text);
mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, clear, 0);
mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, setSize, 2, U32, cols, U32, rows);
mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, moveCursor, 2, U32, x, U32, y);
mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, advance, 1, S32, adv);
mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, setName, 1, CHARP, name);
mSCRIPT_DEFINE_STRUCT(mScriptTextBuffer)
mSCRIPT_DEFINE_CLASS_DOCSTRING(
"An object that can be used to present texual data to the user. It is displayed monospaced, "
"and text can be edited after sending by moving the cursor or clearing the buffer."
)
mSCRIPT_DEFINE_STRUCT_DEINIT_NAMED(mScriptTextBuffer, deinit)
mSCRIPT_DEFINE_DOCSTRING("Get the current x position of the cursor")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, getX)
mSCRIPT_DEFINE_DOCSTRING("Get the current y position of the cursor")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, getY)
mSCRIPT_DEFINE_DOCSTRING("Get number of columns in the buffer")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, cols)
mSCRIPT_DEFINE_DOCSTRING("Get number of rows in the buffer")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, rows)
mSCRIPT_DEFINE_DOCSTRING("Print a string to the buffer")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, print)
mSCRIPT_DEFINE_DOCSTRING("Clear the buffer")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, clear)
mSCRIPT_DEFINE_DOCSTRING("Set the number of rows and columns")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, setSize)
mSCRIPT_DEFINE_DOCSTRING("Set the position of the cursor")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, moveCursor)
mSCRIPT_DEFINE_DOCSTRING("Advance the cursor a number of columns")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, advance)
mSCRIPT_DEFINE_DOCSTRING("Set the user-visible name of this buffer")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, setName)
mSCRIPT_DEFINE_END;
void mScriptContextSetTextBufferFactory(struct mScriptContext* context, mScriptContextBufferFactory factory, void* cbContext) {
struct mScriptConsole* console = _ensureConsole(context);
console->textBufferFactory = factory;
console->textBufferContext = cbContext;
}

View File

@ -10,6 +10,7 @@
#include <QTextCursor> #include <QTextCursor>
#include <QTextDocument> #include <QTextDocument>
#include <mgba/script/console.h>
#include <mgba/core/scripting.h> #include <mgba/core/scripting.h>
namespace QGBA { namespace QGBA {

View File

@ -1,6 +1,7 @@
include(ExportDirectory) include(ExportDirectory)
set(SOURCE_FILES set(SOURCE_FILES
canvas.c canvas.c
console.c
context.c context.c
input.c input.c
image.c image.c

141
src/script/console.c Normal file
View File

@ -0,0 +1,141 @@
/* Copyright (c) 2013-2024 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <mgba/script/console.h>
#include <mgba/script/context.h>
struct mScriptConsole {
struct mLogger* logger;
mScriptContextBufferFactory textBufferFactory;
void* textBufferContext;
};
static struct mScriptTextBuffer* _mScriptConsoleCreateBuffer(struct mScriptConsole* lib, const char* name) {
struct mScriptTextBuffer* buffer = lib->textBufferFactory(lib->textBufferContext);
buffer->init(buffer, name);
return buffer;
}
static void mScriptConsoleLog(struct mScriptConsole* console, const char* msg) {
if (console->logger) {
mLogExplicit(console->logger, _mLOG_CAT_SCRIPT, mLOG_INFO, "%s", msg);
} else {
mLog(_mLOG_CAT_SCRIPT, mLOG_INFO, "%s", msg);
}
}
static void mScriptConsoleWarn(struct mScriptConsole* console, const char* msg) {
if (console->logger) {
mLogExplicit(console->logger, _mLOG_CAT_SCRIPT, mLOG_WARN, "%s", msg);
} else {
mLog(_mLOG_CAT_SCRIPT, mLOG_WARN, "%s", msg);
}
}
static void mScriptConsoleError(struct mScriptConsole* console, const char* msg) {
if (console->logger) {
mLogExplicit(console->logger, _mLOG_CAT_SCRIPT, mLOG_ERROR, "%s", msg);
} else {
mLog(_mLOG_CAT_SCRIPT, mLOG_ERROR, "%s", msg);
}
}
mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptConsole, log, mScriptConsoleLog, 1, CHARP, msg);
mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptConsole, warn, mScriptConsoleWarn, 1, CHARP, msg);
mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptConsole, error, mScriptConsoleError, 1, CHARP, msg);
mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mScriptConsole, S(mScriptTextBuffer), createBuffer, _mScriptConsoleCreateBuffer, 1, CHARP, name);
mSCRIPT_DEFINE_STRUCT(mScriptConsole)
mSCRIPT_DEFINE_CLASS_DOCSTRING(
"A global singleton object `console` that can be used for presenting textual information to the user via a console."
)
mSCRIPT_DEFINE_DOCSTRING("Print a log to the console")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptConsole, log)
mSCRIPT_DEFINE_DOCSTRING("Print a warning to the console")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptConsole, warn)
mSCRIPT_DEFINE_DOCSTRING("Print an error to the console")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptConsole, error)
mSCRIPT_DEFINE_DOCSTRING("Create a text buffer that can be used to display custom information")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptConsole, createBuffer)
mSCRIPT_DEFINE_END;
mSCRIPT_DEFINE_STRUCT_BINDING_DEFAULTS(mScriptConsole, createBuffer)
mSCRIPT_CHARP(NULL)
mSCRIPT_DEFINE_DEFAULTS_END;
static struct mScriptConsole* _ensureConsole(struct mScriptContext* context) {
struct mScriptValue* value = mScriptContextGetGlobal(context, "console");
if (value) {
return value->value.opaque;
}
struct mScriptConsole* console = calloc(1, sizeof(*console));
value = mScriptValueAlloc(mSCRIPT_TYPE_MS_S(mScriptConsole));
value->value.opaque = console;
value->flags = mSCRIPT_VALUE_FLAG_FREE_BUFFER;
mScriptContextSetGlobal(context, "console", value);
mScriptContextSetDocstring(context, "console", "Singleton instance of struct::mScriptConsole");
return console;
}
void mScriptContextAttachLogger(struct mScriptContext* context, struct mLogger* logger) {
struct mScriptConsole* console = _ensureConsole(context);
console->logger = logger;
}
void mScriptContextDetachLogger(struct mScriptContext* context) {
struct mScriptValue* value = mScriptContextGetGlobal(context, "console");
if (!value) {
return;
}
struct mScriptConsole* console = value->value.opaque;
console->logger = mLogGetContext();
}
mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, deinit, 0);
mSCRIPT_DECLARE_STRUCT_CD_METHOD(mScriptTextBuffer, U32, getX, 0);
mSCRIPT_DECLARE_STRUCT_CD_METHOD(mScriptTextBuffer, U32, getY, 0);
mSCRIPT_DECLARE_STRUCT_CD_METHOD(mScriptTextBuffer, U32, cols, 0);
mSCRIPT_DECLARE_STRUCT_CD_METHOD(mScriptTextBuffer, U32, rows, 0);
mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, print, 1, CHARP, text);
mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, clear, 0);
mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, setSize, 2, U32, cols, U32, rows);
mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, moveCursor, 2, U32, x, U32, y);
mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, advance, 1, S32, adv);
mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, setName, 1, CHARP, name);
mSCRIPT_DEFINE_STRUCT(mScriptTextBuffer)
mSCRIPT_DEFINE_CLASS_DOCSTRING(
"An object that can be used to present texual data to the user. It is displayed monospaced, "
"and text can be edited after sending by moving the cursor or clearing the buffer."
)
mSCRIPT_DEFINE_STRUCT_DEINIT_NAMED(mScriptTextBuffer, deinit)
mSCRIPT_DEFINE_DOCSTRING("Get the current x position of the cursor")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, getX)
mSCRIPT_DEFINE_DOCSTRING("Get the current y position of the cursor")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, getY)
mSCRIPT_DEFINE_DOCSTRING("Get number of columns in the buffer")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, cols)
mSCRIPT_DEFINE_DOCSTRING("Get number of rows in the buffer")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, rows)
mSCRIPT_DEFINE_DOCSTRING("Print a string to the buffer")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, print)
mSCRIPT_DEFINE_DOCSTRING("Clear the buffer")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, clear)
mSCRIPT_DEFINE_DOCSTRING("Set the number of rows and columns")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, setSize)
mSCRIPT_DEFINE_DOCSTRING("Set the position of the cursor")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, moveCursor)
mSCRIPT_DEFINE_DOCSTRING("Advance the cursor a number of columns")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, advance)
mSCRIPT_DEFINE_DOCSTRING("Set the user-visible name of this buffer")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, setName)
mSCRIPT_DEFINE_END;
void mScriptContextSetTextBufferFactory(struct mScriptContext* context, mScriptContextBufferFactory factory, void* cbContext) {
struct mScriptConsole* console = _ensureConsole(context);
console->textBufferFactory = factory;
console->textBufferContext = cbContext;
}