mirror of https://github.com/mgba-emu/mgba.git
Python: Add runner, thread interfaces
This commit is contained in:
parent
e1325b0373
commit
dce49ea990
|
@ -1,5 +1,6 @@
|
|||
#define COMMON_H
|
||||
#define PNG_H
|
||||
#define OPAQUE_THREADING
|
||||
#define _SYS_TIME_H
|
||||
#define _SYS_TIME_H_
|
||||
#define _TIME_H
|
||||
|
@ -30,6 +31,7 @@ void free(void*);
|
|||
#include <mgba/core/core.h>
|
||||
#include <mgba/core/mem-search.h>
|
||||
#include <mgba/core/tile-cache.h>
|
||||
#include <mgba/core/thread.h>
|
||||
#include <mgba/core/version.h>
|
||||
|
||||
#define PYEXPORT extern "Python+C"
|
||||
|
|
|
@ -18,10 +18,12 @@ cppflags.extend(["-I" + incdir, "-I" + srcdir, "-I" + bindir])
|
|||
|
||||
ffi.set_source("mgba._pylib", """
|
||||
#include "flags.h"
|
||||
#define OPAQUE_THREADING
|
||||
#include <mgba-util/common.h>
|
||||
#include <mgba/core/core.h>
|
||||
#include <mgba/core/log.h>
|
||||
#include <mgba/core/mem-search.h>
|
||||
#include <mgba/core/thread.h>
|
||||
#include <mgba/core/tile-cache.h>
|
||||
#include <mgba/core/version.h>
|
||||
#include <mgba/internal/arm/arm.h>
|
||||
|
|
|
@ -38,10 +38,18 @@ def needsReset(f):
|
|||
return f(self, *args, **kwargs)
|
||||
return wrapper
|
||||
|
||||
def protected(f):
|
||||
def wrapper(self, *args, **kwargs):
|
||||
if self._protected:
|
||||
raise RuntimeError("Core is protected")
|
||||
return f(self, *args, **kwargs)
|
||||
return wrapper
|
||||
|
||||
class Core(object):
|
||||
def __init__(self, native):
|
||||
self._core = native
|
||||
self._wasReset = False
|
||||
self._protected = False
|
||||
|
||||
@cached_property
|
||||
def tiles(self):
|
||||
|
@ -51,6 +59,7 @@ class Core(object):
|
|||
def _init(cls, native):
|
||||
core = ffi.gc(native, native.deinit)
|
||||
success = bool(core.init(core))
|
||||
lib.mCoreInitConfig(core, ffi.NULL)
|
||||
if not success:
|
||||
raise RuntimeError("Failed to initialize core")
|
||||
if hasattr(cls, 'PLATFORM_GBA') and core.platform(core) == cls.PLATFORM_GBA:
|
||||
|
@ -62,6 +71,7 @@ class Core(object):
|
|||
def _deinit(self):
|
||||
self._core.deinit(self._core)
|
||||
|
||||
@protected
|
||||
def loadFile(self, path):
|
||||
return bool(lib.mCoreLoadFile(self._core, path.encode('UTF-8')))
|
||||
|
||||
|
@ -77,6 +87,7 @@ class Core(object):
|
|||
def loadTemporarySave(self, vf):
|
||||
return bool(self._core.loadTemporarySave(self._core, vf.handle))
|
||||
|
||||
@protected
|
||||
def loadPatch(self, vf):
|
||||
return bool(self._core.loadPatch(self._core, vf.handle))
|
||||
|
||||
|
@ -98,19 +109,23 @@ class Core(object):
|
|||
def setVideoBuffer(self, image):
|
||||
self._core.setVideoBuffer(self._core, image.buffer, image.stride)
|
||||
|
||||
@protected
|
||||
def reset(self):
|
||||
self._core.reset(self._core)
|
||||
self._wasReset = True
|
||||
|
||||
@needsReset
|
||||
@protected
|
||||
def runFrame(self):
|
||||
self._core.runFrame(self._core)
|
||||
|
||||
@needsReset
|
||||
@protected
|
||||
def runLoop(self):
|
||||
self._core.runLoop(self._core)
|
||||
|
||||
@needsReset
|
||||
@protected
|
||||
def step(self):
|
||||
self._core.step(self._core)
|
||||
|
||||
|
@ -152,6 +167,38 @@ class Core(object):
|
|||
self._core.getGameCode(self._core, code)
|
||||
return ffi.string(code, 12).decode("ascii")
|
||||
|
||||
class ICoreOwner(object):
|
||||
def claim(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def release(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def __enter__(self):
|
||||
self.core = self.claim()
|
||||
self.core._protected = True
|
||||
return self.core
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
self.core._protected = False
|
||||
self.release()
|
||||
|
||||
class IRunner(object):
|
||||
def pause(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def unpause(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def useCore(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def isRunning(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def isPaused(self):
|
||||
raise NotImplementedError
|
||||
|
||||
if hasattr(lib, 'PLATFORM_GBA'):
|
||||
from .gba import GBA
|
||||
Core.PLATFORM_GBA = lib.PLATFORM_GBA
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
# Copyright (c) 2013-2017 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/.
|
||||
from ._pylib import ffi, lib
|
||||
from .core import IRunner, ICoreOwner, Core
|
||||
|
||||
class ThreadCoreOwner(ICoreOwner):
|
||||
def __init__(self, thread):
|
||||
self.thread = thread
|
||||
|
||||
def claim(self):
|
||||
if not self.thread.isRunning():
|
||||
raise ValueError
|
||||
lib.mCoreThreadInterrupt(self.thread._native)
|
||||
return self.thread._core
|
||||
|
||||
def release(self):
|
||||
lib.mCoreThreadContinue(self.thread._native)
|
||||
|
||||
class Thread(IRunner):
|
||||
def __init__(self, native=None):
|
||||
if native:
|
||||
self._native = native
|
||||
self._core = Core(native.core)
|
||||
self._core._wasReset = lib.mCoreThreadHasStarted(self._native)
|
||||
else:
|
||||
self._native = ffi.new("struct mCoreThread*")
|
||||
|
||||
def start(self, core):
|
||||
if lib.mCoreThreadHasStarted(self._native):
|
||||
raise ValueError
|
||||
self._core = core
|
||||
self._native.core = core._core
|
||||
lib.mCoreThreadStart(self._native)
|
||||
self._core._wasReset = lib.mCoreThreadHasStarted(self._native)
|
||||
|
||||
def end(self):
|
||||
if not lib.mCoreThreadHasStarted(self._native):
|
||||
raise ValueError
|
||||
lib.mCoreThreadEnd(self._native)
|
||||
lib.mCoreThreadJoin(self._native)
|
||||
|
||||
def pause(self):
|
||||
lib.mCoreThreadPause(self._native)
|
||||
|
||||
def unpause(self):
|
||||
lib.mCoreThreadUnpause(self._native)
|
||||
|
||||
def isRunning(self):
|
||||
return bool(lib.mCoreThreadIsActive(self._native))
|
||||
|
||||
def isPaused(self):
|
||||
return bool(lib.mCoreThreadIsPaused(self._native))
|
||||
|
||||
def useCore(self):
|
||||
return ThreadCoreOwner(self)
|
Loading…
Reference in New Issue