1
0
mirror of https://github.com/moparisthebest/Simba synced 2024-12-24 16:28:53 -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} {$R *.res}
type
PTPoint = ^TPoint;
Const Const
RESULT_OK = 0; RESULT_OK = 0;
RESULT_FALSE = 1; RESULT_FALSE = 1;
@ -20,22 +16,106 @@ Const
MOUSE_DOWN = 1; MOUSE_DOWN = 1;
var var
C: TClient;
gr: Pointer;
last_error: PChar; last_error: PChar;
debug: boolean;
function init: integer;
function init: integer; cdecl;
begin begin
C:=TClient.Create(''); last_error := '';
result:=0; 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; end;
{ Mouse } { Mouse }
function getMousePos(var t: tpoint): integer; cdecl; function get_mouse_pos(C: TClient; var t: tpoint): integer; cdecl;
begin begin
if not validate_client(C) then
begin
exit(RESULT_ERROR);
end;
try try
C.IOManager.GetMousePos(t.x,t.y); C.IOManager.GetMousePos(t.x,t.y);
result := RESULT_OK; result := RESULT_OK;
@ -47,8 +127,13 @@ begin
end; end;
end; end;
function setMousePos(var t: tpoint): integer; cdecl; function set_mouse_pos(C: TClient; var t: tpoint): integer; cdecl;
begin begin
if not validate_client(C) then
begin
exit(RESULT_ERROR);
end;
try try
C.IOManager.MoveMouse(t.x,t.y); C.IOManager.MoveMouse(t.x,t.y);
result := RESULT_OK; result := RESULT_OK;
@ -60,7 +145,7 @@ begin
end; end;
end; end;
function ConvIntClickType(Int : Integer) : TClickType;inline; function ConvIntClickType(Int : Integer) : TClickType; inline;
begin begin
case int of case int of
0 : result := mouse_Left; 0 : result := mouse_Left;
@ -69,8 +154,14 @@ begin
end; end;
end; end;
function getMouseButtonState(But: Integer): Integer; function get_mouse_button_state(C: TClient; But: Integer): Integer;
begin begin
if not validate_client(C) then
begin
exit(RESULT_ERROR);
end;
writeln(but);
try try
if C.IOManager.IsMouseButtonDown(ConvIntClickType(But)) then if C.IOManager.IsMouseButtonDown(ConvIntClickType(But)) then
result := MOUSE_DOWN; result := MOUSE_DOWN;
@ -82,8 +173,13 @@ begin
end; end;
end; end;
function setMouseButtonState(But, State, X, Y: Integer): Integer; function set_mouse_button_state(C: TClient; But, State, X, Y: Integer): Integer;
begin begin
if not validate_client(C) then
begin
exit(RESULT_ERROR);
end;
try try
if State = MOUSE_UP then if State = MOUSE_UP then
begin begin
@ -102,8 +198,13 @@ begin
end; end;
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 begin
if not validate_client(C) then
begin
exit(RESULT_ERROR);
end;
try try
if C.MFinder.FindColor(x, y, color, x1, y1, x2, y2) then if C.MFinder.FindColor(x, y, color, x1, y1, x2, y2) then
result := RESULT_OK result := RESULT_OK
@ -117,8 +218,14 @@ begin
end; end;
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 begin
if not validate_client(C) then
begin
exit(RESULT_ERROR);
end;
try try
if C.MFinder.FindColorTolerance(x, y, color, x1, y1, x2, y2, tol) then if C.MFinder.FindColorTolerance(x, y, color, x1, y1, x2, y2, tol) then
result := RESULT_OK result := RESULT_OK
@ -132,10 +239,16 @@ begin
end; end;
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 var
TPA: TPointArray; TPA: TPointArray;
begin begin
if not validate_client(C) then
begin
exit(RESULT_ERROR);
end;
SetLength(TPA, 0);
try try
C.MFinder.FindColors(TPA, color, x1, y1, x2, y2); C.MFinder.FindColors(TPA, color, x1, y1, x2, y2);
except on e : Exception do except on e : Exception do
@ -144,15 +257,22 @@ begin
last_error := PChar(e.Message); last_error := PChar(e.Message);
end; end;
end; end;
ptr := AllocMem(sizeof(tpoint) * (length(TPA) + 1));
PInteger(ptr)[0] := length(TPA); len := Length(TPA);
Move(TPA[0], ptr[1], length(TPA)*sizeof(tpoint)); ptr := array_to_ptr(Pointer(@TPA[0]), len, sizeof(TPoint));
result := RESULT_OK;
setlength(tpa, 0);
end; 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 var
TPA: TPointArray; TPA: TPointArray;
begin begin
if not validate_client(C) then
begin
exit(RESULT_ERROR);
end;
try try
C.MFinder.FindColorsTolerance(TPA, color, x1, y1, x2, y2, tol); C.MFinder.FindColorsTolerance(TPA, color, x1, y1, x2, y2, tol);
except on e : Exception do except on e : Exception do
@ -161,45 +281,29 @@ begin
last_error := PChar(e.Message); last_error := PChar(e.Message);
end; end;
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; len := Length(TPA);
begin ptr := array_to_ptr(Pointer(@TPA[0]), len, sizeof(TPoint));
freemem(pointer(ptruint(p))); result := RESULT_OK;
end; 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 exports
init, init,
{ Mouse } create_client,
getMousePos, get_last_error,
setMousePos, get_debug,
getMouseButtonState, set_debug,
setMouseButtonState, alloc_mem,
realloc_mem,
free_ptr,
{ Finder } get_mouse_pos, set_mouse_pos,
findColor, get_mouse_button_state, set_mouse_button_state,
findColors,
findColorTolerance,
findColorsTolerance,
{ Mem Management } find_color, find_color_tolerance,
fpc_freemem_,
fpc_allocmem_, find_colors, find_colors_tolerance;
fpc_reallocmem_;
begin begin

View File

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

View File

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

View File

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

View File

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