1 /* Copyright (c) 2013-2016 Jeffrey Pfau
2  *
3  * This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "engine.h"
7 
8 #include <mgba/core/scripting.h>
9 #include <mgba-util/string.h>
10 #include <mgba-util/vfs.h>
11 
12 #ifdef USE_DEBUGGERS
13 #include <mgba/debugger/debugger.h>
14 #endif
15 
16 #include "lib.h"
17 
18 static const char* mPythonScriptEngineName(struct mScriptEngine*);
19 static bool mPythonScriptEngineInit(struct mScriptEngine*, struct mScriptBridge*);
20 static void mPythonScriptEngineDeinit(struct mScriptEngine*);
21 static bool mPythonScriptEngineIsScript(struct mScriptEngine*, const char* name, struct VFile* vf);
22 static bool mPythonScriptEngineLoadScript(struct mScriptEngine*, const char* name, struct VFile* vf);
23 static void mPythonScriptEngineRun(struct mScriptEngine*);
24 static bool mPythonScriptEngineLookupSymbol(struct mScriptEngine*, const char* name, int32_t* out);
25 
26 #ifdef USE_DEBUGGERS
27 static void mPythonScriptDebuggerEntered(struct mScriptEngine*, enum mDebuggerEntryReason, struct mDebuggerEntryInfo*);
28 #endif
29 
30 struct mPythonScriptEngine {
31 	struct mScriptEngine d;
32 	struct mScriptBridge* sb;
33 };
34 
mPythonCreateScriptEngine(void)35 struct mPythonScriptEngine* mPythonCreateScriptEngine(void) {
36 	struct mPythonScriptEngine* engine = malloc(sizeof(*engine));
37 	engine->d.name = mPythonScriptEngineName;
38 	engine->d.init = mPythonScriptEngineInit;
39 	engine->d.deinit = mPythonScriptEngineDeinit;
40 	engine->d.isScript = mPythonScriptEngineIsScript;
41 	engine->d.loadScript = mPythonScriptEngineLoadScript;
42 	engine->d.run = mPythonScriptEngineRun;
43 	engine->d.lookupSymbol = mPythonScriptEngineLookupSymbol;
44 #ifdef USE_DEBUGGERS
45 	engine->d.debuggerEntered = mPythonScriptDebuggerEntered;
46 #endif
47 	engine->sb = NULL;
48 	return engine;
49 }
50 
mPythonSetup(struct mScriptBridge * sb)51 void mPythonSetup(struct mScriptBridge* sb) {
52 	struct mPythonScriptEngine* se = mPythonCreateScriptEngine();
53 	mScriptBridgeInstallEngine(sb, &se->d);
54 }
55 
mPythonScriptEngineName(struct mScriptEngine * se)56 const char* mPythonScriptEngineName(struct mScriptEngine* se) {
57 	UNUSED(se);
58 	return "python";
59 }
60 
mPythonScriptEngineInit(struct mScriptEngine * se,struct mScriptBridge * sb)61 bool mPythonScriptEngineInit(struct mScriptEngine* se, struct mScriptBridge* sb) {
62 	struct mPythonScriptEngine* engine = (struct mPythonScriptEngine*) se;
63 	engine->sb = sb;
64 	return true;
65 }
66 
mPythonScriptEngineDeinit(struct mScriptEngine * se)67 void mPythonScriptEngineDeinit(struct mScriptEngine* se) {
68 	free(se);
69 }
70 
mPythonScriptEngineIsScript(struct mScriptEngine * se,const char * name,struct VFile * vf)71 bool mPythonScriptEngineIsScript(struct mScriptEngine* se, const char* name, struct VFile* vf) {
72 	UNUSED(se);
73 	UNUSED(vf);
74 	return endswith(name, ".py");
75 }
76 
mPythonScriptEngineLoadScript(struct mScriptEngine * se,const char * name,struct VFile * vf)77 bool mPythonScriptEngineLoadScript(struct mScriptEngine* se, const char* name, struct VFile* vf) {
78 	UNUSED(se);
79 	return mPythonLoadScript(name, vf);
80 }
81 
mPythonScriptEngineRun(struct mScriptEngine * se)82 void mPythonScriptEngineRun(struct mScriptEngine* se) {
83 	struct mPythonScriptEngine* engine = (struct mPythonScriptEngine*) se;
84 
85 #ifdef USE_DEBUGGERS
86 	struct mDebugger* debugger = mScriptBridgeGetDebugger(engine->sb);
87 	if (debugger) {
88 		mPythonSetDebugger(debugger);
89 	}
90 #endif
91 
92 	mPythonRunPending();
93 }
94 
mPythonScriptEngineLookupSymbol(struct mScriptEngine * se,const char * name,int32_t * out)95 bool mPythonScriptEngineLookupSymbol(struct mScriptEngine* se, const char* name, int32_t* out) {
96 	UNUSED(se);
97 	return mPythonLookupSymbol(name, out);
98 }
99 
100 #ifdef USE_DEBUGGERS
mPythonScriptDebuggerEntered(struct mScriptEngine * se,enum mDebuggerEntryReason reason,struct mDebuggerEntryInfo * info)101 void mPythonScriptDebuggerEntered(struct mScriptEngine* se, enum mDebuggerEntryReason reason, struct mDebuggerEntryInfo* info) {
102 	struct mPythonScriptEngine* engine = (struct mPythonScriptEngine*) se;
103 
104 	struct mDebugger* debugger = mScriptBridgeGetDebugger(engine->sb);
105 	if (!debugger) {
106 		return;
107 	}
108 
109 	mPythonSetDebugger(debugger);
110 	mPythonDebuggerEntered(reason, info);
111 }
112 #endif
113