1
0
mirror of https://github.com/moparisthebest/Simba synced 2024-12-24 00:08:52 -05:00

Big changes to libMML and PyMML.

*   Support multiple clients.
*   Support for array passing. (Copied on FPC side)
*   Partially new coding convention.
This commit is contained in:
Merlijn Wajer 2010-09-05 20:43:45 +02:00
parent 1d17f75796
commit a65983437e
5 changed files with 312 additions and 190 deletions

View File

@ -7,10 +7,6 @@ uses
{$R *.res}
type
PTPoint = ^TPoint;
Const
RESULT_OK = 0;
RESULT_FALSE = 1;
@ -20,22 +16,106 @@ Const
MOUSE_DOWN = 1;
var
C: TClient;
gr: Pointer;
last_error: PChar;
debug: boolean;
function init: integer; cdecl;
function init: integer;
begin
C:=TClient.Create('');
result:=0;
last_error := '';
debug := true;
result := RESULT_OK;
end;
function validate_client(C: TClient): boolean; inline;
begin
result := Assigned(C);
if not result then
begin
last_error := PChar('PClient is NULL');
if debug then
writeln(last_error);
end;
end;
function create_client: PtrUInt; cdecl;
var
C: TClient;
begin
try
C := TClient.Create('');
Result := PtrUInt(C);
except on e : Exception do
begin
writeln('ERROR');
result := PtrUInt(RESULT_ERROR);
last_error := PChar(e.Message);
end;
end;
writeln(format('C: %d, IOManager: %d', [PtrUInt(C), PtrUInt(C.IOManager)]));
end;
function destroy_client(C: TClient): integer;
begin
if not validate_client(C) then
begin
exit(RESULT_ERROR);
end;
C.Free;
end;
procedure set_debug(v: Boolean);
begin
debug := v;
end;
function get_debug: boolean;
begin
exit(debug);
end;
function get_last_error: pchar;
begin
exit(last_error);
end;
function array_to_ptr(ptr: Pointer; size: PtrUInt; objsize: PtrUInt): Pointer;
begin
result := GetMem(objsize * size);
Move(ptr^, result^, objsize * size);
end;
function free_ptr(ptr: pointer): boolean;
begin
result := Assigned(ptr);
if not result then
begin
last_error := PChar('TClient is NULL');
if debug then
writeln(last_error);
end else
Free(ptr);
end;
function alloc_mem(size, objsize: PtrUInt): Pointer;
begin
result := GetMem(size * objsize);
end;
function realloc_mem(ptr: Pointer; size, objsize: PtrUInt): Pointer;
begin
result := ReAlloc(ptr, size*objsize);
end;
{ Mouse }
function getMousePos(var t: tpoint): integer; cdecl;
function get_mouse_pos(C: TClient; var t: tpoint): integer; cdecl;
begin
if not validate_client(C) then
begin
exit(RESULT_ERROR);
end;
try
C.IOManager.GetMousePos(t.x,t.y);
result := RESULT_OK;
@ -47,8 +127,13 @@ begin
end;
end;
function setMousePos(var t: tpoint): integer; cdecl;
function set_mouse_pos(C: TClient; var t: tpoint): integer; cdecl;
begin
if not validate_client(C) then
begin
exit(RESULT_ERROR);
end;
try
C.IOManager.MoveMouse(t.x,t.y);
result := RESULT_OK;
@ -60,7 +145,7 @@ begin
end;
end;
function ConvIntClickType(Int : Integer) : TClickType;inline;
function ConvIntClickType(Int : Integer) : TClickType; inline;
begin
case int of
0 : result := mouse_Left;
@ -69,8 +154,14 @@ begin
end;
end;
function getMouseButtonState(But: Integer): Integer;
function get_mouse_button_state(C: TClient; But: Integer): Integer;
begin
if not validate_client(C) then
begin
exit(RESULT_ERROR);
end;
writeln(but);
try
if C.IOManager.IsMouseButtonDown(ConvIntClickType(But)) then
result := MOUSE_DOWN;
@ -82,8 +173,13 @@ begin
end;
end;
function setMouseButtonState(But, State, X, Y: Integer): Integer;
function set_mouse_button_state(C: TClient; But, State, X, Y: Integer): Integer;
begin
if not validate_client(C) then
begin
exit(RESULT_ERROR);
end;
try
if State = MOUSE_UP then
begin
@ -102,8 +198,13 @@ begin
end;
end;
function findColor(var x, y: integer; color, x1, y1, x2, y2: integer): integer;
function find_color(C: TClient; var x, y: integer; color, x1, y1, x2, y2: integer): integer;
begin
if not validate_client(C) then
begin
exit(RESULT_ERROR);
end;
try
if C.MFinder.FindColor(x, y, color, x1, y1, x2, y2) then
result := RESULT_OK
@ -117,8 +218,14 @@ begin
end;
end;
function findColorTolerance(var x, y: integer; color, tol, x1, y1, x2, y2: integer): integer;
function find_color_tolerance(C: TClient; var x, y: integer; color, tol, x1, y1, x2, y2: integer): integer;
begin
if not validate_client(C) then
begin
exit(RESULT_ERROR);
end;
try
if C.MFinder.FindColorTolerance(x, y, color, x1, y1, x2, y2, tol) then
result := RESULT_OK
@ -132,10 +239,16 @@ begin
end;
end;
function findColors(var ptr: PTPoint; color, x1, y1, x2, y2: integer): integer;
function find_colors(C: TClient; var ptr: PPoint; var len: Integer; color, x1, y1, x2, y2: integer): integer;
var
TPA: TPointArray;
begin
if not validate_client(C) then
begin
exit(RESULT_ERROR);
end;
SetLength(TPA, 0);
try
C.MFinder.FindColors(TPA, color, x1, y1, x2, y2);
except on e : Exception do
@ -144,15 +257,22 @@ begin
last_error := PChar(e.Message);
end;
end;
ptr := AllocMem(sizeof(tpoint) * (length(TPA) + 1));
PInteger(ptr)[0] := length(TPA);
Move(TPA[0], ptr[1], length(TPA)*sizeof(tpoint));
len := Length(TPA);
ptr := array_to_ptr(Pointer(@TPA[0]), len, sizeof(TPoint));
result := RESULT_OK;
setlength(tpa, 0);
end;
function findColorsTolerance(var ptr: PTPoint; color, tol, x1, y1, x2, y2: integer): integer;
function find_colors_tolerance(C: TClient; var ptr: PPoint; var len: Integer; color, tol, x1, y1, x2, y2: integer): integer;
var
TPA: TPointArray;
begin
if not validate_client(C) then
begin
exit(RESULT_ERROR);
end;
try
C.MFinder.FindColorsTolerance(TPA, color, x1, y1, x2, y2, tol);
except on e : Exception do
@ -161,45 +281,29 @@ begin
last_error := PChar(e.Message);
end;
end;
ptr := AllocMem(sizeof(tpoint) * (length(TPA) + 1));
PInteger(ptr)[0] := length(TPA);
Move(TPA[0], ptr[1], length(TPA)*sizeof(tpoint));
end;
procedure fpc_freemem_(p:pointer); cdecl;
begin
freemem(pointer(ptruint(p)));
len := Length(TPA);
ptr := array_to_ptr(Pointer(@TPA[0]), len, sizeof(TPoint));
result := RESULT_OK;
end;
function fpc_allocmem_(size: ptruint): pointer; cdecl;
begin
result:= AllocMem(size);
end;
function fpc_reallocmem_(size: ptruint; ptr: pointer): pointer;
begin
result:= ReAllocMem(ptr, size);
end;
exports
init,
{ Mouse }
getMousePos,
setMousePos,
getMouseButtonState,
setMouseButtonState,
create_client,
get_last_error,
get_debug,
set_debug,
alloc_mem,
realloc_mem,
free_ptr,
{ Finder }
findColor,
findColors,
findColorTolerance,
findColorsTolerance,
get_mouse_pos, set_mouse_pos,
get_mouse_button_state, set_mouse_button_state,
{ Mem Management }
fpc_freemem_,
fpc_allocmem_,
fpc_reallocmem_;
find_color, find_color_tolerance,
find_colors, find_colors_tolerance;
begin

View File

@ -19,6 +19,8 @@ class MMLCore(object):
self.dll.init.restype = c_int
self.dll.init.argtypes = None
self.dll.create_client.restype = c_ulong
self.dll.create_client.argtypes = None
if self.dll.init() != 0:
del self.dll
raise MMLCoreException("Could not initialize the DLL")
@ -30,32 +32,41 @@ class MMLCore(object):
if __name__ == '__main__':
DLL = MMLCore('../libmml.so')
c = Color(DLL)
client = DLL.dll.create_client()
print 'Python Client: %d' % client
if client in (0, 1):
raise Exception('Could create a client');
c = Color(DLL, client)
ret = c.find((0, 0, 100, 100), 0)
print ret
ret = c.findAll((0, 0, 100, 100), 0)
print ret
raise Exception('WAT')
m = Mouse(DLL)
m = Mouse(DLL, client)
print m[(Mouse.Pos, Mouse.Left, Mouse.Right)]
m[(Mouse.Pos, Mouse.Right)] = ((300,300), True)
print m.getButtonStates()
sleep(0.5)
m.setPos((200,200))
sleep(2)
# Reset all buttons..
print 'Done'
#
# # Reset all buttons..
m[(Mouse.Left, Mouse.Right, Mouse.Middle)] = [False for x in range(3)]
for v in zip((Mouse.Left, Mouse.Right), m[(Mouse.Left, Mouse.Right)]):
print v
print m.getPos()
if hasattr(ret,'__iter__'):
m.setPos(ret)
# if hasattr(ret,'__iter__'):
# m.setPos(ret)
del DLL

View File

@ -1,7 +1,6 @@
from ctypes import *
from mmltypes import isiterable
from mmltypes import POINT, PPOINT, PINTEGER
from mmltypes import PascalArray
from mmltypes import RESULT_OK, RESULT_FALSE, RESULT_ERROR
"""
@ -25,11 +24,12 @@ class Color(object):
_mc = None
def __init__(self, MC):
def __init__(self, MC, cli):
"""
Initialise the Color object.
"""
self._mc = MC
self._cli = cli
self._initialiseDLLFuncs()
def find(self, box, color, tol = 0):
@ -40,10 +40,11 @@ class Color(object):
"""
x, y = (c_int(-1), c_int(-1))
if tol is 0:
ret = self._mc.dll.findColor(byref(x), byref(y), color, *box)
ret = self._mc.dll.find_color(self._cli, byref(x), byref(y),
color, *box)
else:
ret = self._mc.dll.findColorTolerance(byref(x), byref(y), color,
tol, *box)
ret = self._mc.dll.find_color_tolerance(self._cli, byref(x),
byref(y), color, tol, *box)
if ret is RESULT_OK:
return (x, y)
@ -55,29 +56,33 @@ class Color(object):
find all colors in a box, with a specific tolerance.
returned are all the matching points
"""
ptr = PPOINT()
ptr, _len = PPOINT(), c_int(42)
print type(_len)
if tol is 0:
self._mc.dll.findColors(byref(ptr), color, *box)
self._mc.dll.find_colors(self._cli, byref(ptr), byref(_len),
color, *box)
else:
self._mc.dll.findColorsTolerance(byref(ptr), color, tol, *box)
self._mc.dll.find_colors_tolerance(self._cli, byref(ptr),
byref(_len), color, tol, *box)
arr = PascalArray(POINT, ptr, self._mc)
# print 'Length:', len(arr)
# for i in range(len(arr)):
# print i, arr[i].x, arr[i].y
# print 'Length:', _len
# for x in range(_len.value):
# print ptr[x].x
# print ptr
# FIXME return python list?
return arr
return ''
def _initialiseDLLFuncs(self):
self._mc.dll.findColor.restype = c_int
self._mc.dll.findColor.argtypes = [PINTEGER, PINTEGER, c_int, c_int,
c_int, c_int, c_int]
self._mc.dll.findColorTolerance.restype = c_int
self._mc.dll.findColorTolerance.argtypes = [PINTEGER, PINTEGER, c_int, c_int,
self._mc.dll.find_color.restype = c_int
self._mc.dll.find_color.argtypes = [c_ulong, PINTEGER, PINTEGER, c_int,
c_int, c_int, c_int, c_int]
self._mc.dll.findColors.restype = c_int
self._mc.dll.findColors.argtypes = [POINTER(PPOINT), c_int, c_int,
c_int, c_int, c_int]
self._mc.dll.findColorsTolerance.restype = c_int
self._mc.dll.findColorsTolerance.argtypes = [POINTER(PPOINT), c_int, c_int,
self._mc.dll.find_color_tolerance.restype = c_int
self._mc.dll.find_color_tolerance.argtypes = [c_ulong, PINTEGER,
PINTEGER, c_int, c_int, c_int, c_int, c_int, c_int]
self._mc.dll.find_colors.restype = c_int
self._mc.dll.find_colors.argtypes = [c_ulong, POINTER(PPOINT),
POINTER(c_int), c_int, c_int, c_int, c_int, c_int]
self._mc.dll.find_colors_tolerance.restype = c_int
self._mc.dll.find_colors_tolerance.argtypes = [c_ulong,
POINTER(PPOINT), POINTER(c_int), c_int, c_int,
c_int, c_int, c_int, c_int]

View File

@ -30,10 +30,11 @@ class Mouse(object):
# last mouse pointer position
_lpp = (0, 0)
def __init__(self, MC):
def __init__(self, MC, cli):
""" Initialize the Mouse object. Needs a DLL Mufasa Core object
(which contains the dll reference.)"""
self._mc = MC
self._cli = cli
self._initialiseDLLFuncs()
pass
@ -132,7 +133,7 @@ class Mouse(object):
# Internal DLL stuff
def _getMousePos(self):
ret = POINT()
ok = self._mc.dll.getMousePos(byref(ret))
ok = self._mc.dll.get_mouse_pos(self._cli, byref(ret))
# FIXME: Perhaps use some sort of assertion?
# We should print dll.last_error is ok != 0
@ -142,37 +143,38 @@ class Mouse(object):
def _setMousePos(self, p):
ret = POINT()
ret.x, ret.y = p
ok = self._mc.dll.setMousePos(byref(ret))
ok = self._mc.dll.set_mouse_pos(self._cli, byref(ret))
if ok != 0:
pass # Raise exception
self._lpp = (ret.x, ret.y)
return ok
def _getMouseButtonState(self, button):
ok = self._mc.dll.getMouseButtonState(button)
ok = self._mc.dll.get_mouse_button_state(self._cli, button)
if ok < 0:
pass #Raise exception
return ok == 1
def _setMouseButtonState(self, button, state):
ok = self._mc.dll.setMouseButtonState(c_int(button), c_int(state),
*map(lambda x: c_int(x), self._getMousePos()))
ok = self._mc.dll.set_mouse_button_state(self._cli, c_int(button),
c_int(state), *map(lambda x: c_int(x), self._getMousePos()))
if ok != 0:
pass # Raise exception
return ok
def _initialiseDLLFuncs(self):
"""Define all mouse related DLL-calls"""
self._mc.dll.getMousePos.restype = c_int
self._mc.dll.getMousePos.argtypes = [PPOINT]
self._mc.dll.get_mouse_pos.restype = c_int
self._mc.dll.get_mouse_pos.argtypes = [c_ulong, PPOINT]
self._mc.dll.setMousePos.restype = c_int
self._mc.dll.setMousePos.argtypes = [PPOINT]
self._mc.dll.set_mouse_pos.restype = c_int
self._mc.dll.set_mouse_pos.argtypes = [c_ulong, PPOINT]
self._mc.dll.getMouseButtonState.restype = c_int
self._mc.dll.getMouseButtonState.argtypes = [c_int]
self._mc.dll.get_mouse_button_state.restype = c_int
self._mc.dll.get_mouse_button_state.argtypes = [c_ulong, c_int]
self._mc.dll.setMouseButtonState.restype = c_int
self._mc.dll.setMouseButtonState.argtypes = [c_int, c_int, c_int, c_int]
self._mc.dll.set_mouse_button_state.restype = c_int
self._mc.dll.set_mouse_button_state.argtypes = [c_ulong, c_int, c_int,
c_int, c_int]
pass

View File

@ -10,63 +10,63 @@ class POINT(Structure):
_fields_ = [('x', c_int),
('y', c_int)]
class PascalArray(object):
"""
PascalArray is a class that allows one to easily use a Pascal-style
array. It has been changed to fit my own Pascal-style arrays. (The
length is no longer stored at -1, but at 0, and the data starts at 1.)
This makes freeing the data much easier.
The implementation is limited to reading and writing data.
It cannot resize arrays nor can it create them.
This class is more like a temporary solution to passing arrays and such.
The actual user should not be bothered by the external memory, so most
likely we will simply turn this data into python lists. The only
drawback would be the overhead created by doing so.
"""
def __init__(self, pastype, ptr, MC):
"""
Set the type of the data we are holding to _pastype_,
save the pointer _ptr_ and store the reference to the MMLCore.
"""
self._type = pastype
self._p = ptr
self._mc = MC
def __del__(self):
"""
Free the array. Perhaps we should do reference counting on the
pointer?
"""
self._mc.dll.fpc_freemem_(self._p)
def __len__(self):
"""
Return the length of the array.
"""
return cast(self._p, POINTER(c_ulong))[0]
def __getitem__(self, pos):
"""
Get an item at a specific position _pos_.
"""
if pos > len(self):
print 'Out of range'
return None
return cast(self._p, POINTER(self._type))[pos+1]
def __setitem__(self, pos, item):
"""
Set an item at a specific position _pos_.
"""
if pos > len(self):
print 'Out of range'
return
if sizeof(item) != sizeof(self._type):
print 'Incorrect structure'
return
cast(self._p, POINTER(self._type))[pos] = item
#class PascalArray(object):
# """
# PascalArray is a class that allows one to easily use a Pascal-style
# array. It has been changed to fit my own Pascal-style arrays. (The
# length is no longer stored at -1, but at 0, and the data starts at 1.)
# This makes freeing the data much easier.
#
# The implementation is limited to reading and writing data.
# It cannot resize arrays nor can it create them.
#
# This class is more like a temporary solution to passing arrays and such.
# The actual user should not be bothered by the external memory, so most
# likely we will simply turn this data into python lists. The only
# drawback would be the overhead created by doing so.
# """
# def __init__(self, pastype, ptr, MC):
# """
# Set the type of the data we are holding to _pastype_,
# save the pointer _ptr_ and store the reference to the MMLCore.
# """
# self._type = pastype
# self._p = ptr
# self._mc = MC
#
# def __del__(self):
# """
# Free the array. Perhaps we should do reference counting on the
# pointer?
# """
# self._mc.dll.fpc_freemem_(self._p)
#
# def __len__(self):
# """
# Return the length of the array.
# """
# return cast(self._p, POINTER(c_ulong))[0]
#
# def __getitem__(self, pos):
# """
# Get an item at a specific position _pos_.
# """
# if pos > len(self):
# print 'Out of range'
# return None
# return cast(self._p, POINTER(self._type))[pos+1]
#
# def __setitem__(self, pos, item):
# """
# Set an item at a specific position _pos_.
# """
# if pos > len(self):
# print 'Out of range'
# return
# if sizeof(item) != sizeof(self._type):
# print 'Incorrect structure'
# return
# cast(self._p, POINTER(self._type))[pos] = item
PPOINT = POINTER(POINT)
PINTEGER = POINTER(c_int)