Commit 77888d9a authored by Guillaume Seguin's avatar Guillaume Seguin

Heavily refactor gcoder to trim memory consumption again

parent 4de130a1
......@@ -69,8 +69,9 @@ class GCodeAnalyzer():
def Analyze(self, gcode):
gline = gcoder.Line(gcode)
split_raw = gcoder.split(gline)
if gline.command.startswith(";@"): return # code is a host command
gline.parse_coordinates(self.imperial)
gcoder.parse_coordinates(gline, split_raw, self.imperial)
code_g = int(gline.command[1:]) if gline.command.startswith("G") else None
code_m = int(gline.command[1:]) if gline.command.startswith("M") else None
......
......@@ -34,45 +34,39 @@ class PyLine(object):
'current_x', 'current_y', 'current_z', 'extruding', 'current_tool',
'gcview_end_vertex')
def __init__(self, l):
self.raw = l
def __getattr__(self, name):
return None
try:
import gcoder_line
LineBase = gcoder_line.GLine
Line = gcoder_line.GLine
except ImportError:
LineBase = PyLine
Line = PyLine
class Line(LineBase):
def split(line):
split_raw = gcode_exp.findall(line.raw.lower())
line.command = split_raw[0].upper() if not split_raw[0].startswith("n") else split_raw[1].upper()
line.is_move = line.command in move_gcodes
return split_raw
__slots__ = ()
def __init__(self, l):
super(Line, self).__init__()
self.raw = l
self.split_raw = gcode_exp.findall(self.raw.lower())
self.command = self.split_raw[0].upper() if not self.split_raw[0].startswith("n") else self.split_raw[1].upper()
self.is_move = self.command in move_gcodes
def parse_coordinates(line, split_raw, imperial = False, force = False):
# Not a G-line, we don't want to parse its arguments
if not force and line.command[0] != "G":
return
if imperial:
for bit in split_raw:
code = bit[0]
if code in gcode_parsed_args and len(bit) > 1:
setattr(line, code, 25.4*float(bit[1:]))
else:
for bit in split_raw:
code = bit[0]
if code in gcode_parsed_args and len(bit) > 1:
setattr(line, code, float(bit[1:]))
def parse_coordinates(self, imperial = False, force = False):
# Not a G-line, we don't want to parse its arguments
if not force and not self.command[0] == "G":
return
if imperial:
for bit in self.split_raw:
code = bit[0]
if code in gcode_parsed_args and len(bit) > 1:
setattr(self, code, 25.4*float(bit[1:]))
else:
for bit in self.split_raw:
code = bit[0]
if code in gcode_parsed_args and len(bit) > 1:
setattr(self, code, float(bit[1:]))
del self.split_raw
def __repr__(self):
return self.raw
class Layer(object):
lines = None
......@@ -192,6 +186,7 @@ class GCode(object):
relative_e = self.relative_e
current_tool = self.current_tool
for line in lines:
split_raw = split(line)
if line.is_move:
line.relative = relative
line.relative_e = relative_e
......@@ -213,7 +208,7 @@ class GCode(object):
elif line.command[0] == "T":
current_tool = int(line.command[1:])
if line.command[0] == "G":
line.parse_coordinates(imperial)
parse_coordinates(line, split_raw, imperial)
self.imperial = imperial
self.relative = relative
self.relative_e = relative_e
......@@ -408,6 +403,7 @@ def main():
print "usage: %s filename.gcode" % sys.argv[0]
return
print "Line object size:", sys.getsizeof(Line("G0 X0"))
gcode = GCode(open(sys.argv[1]))
print "Dimensions:"
......
......@@ -47,9 +47,8 @@ cdef enum BitPos:
pos_current_z = 1 << 15
pos_current_tool = 1 << 16
pos_raw = 1 << 17
pos_split_raw = 1 << 18
pos_command = 1 << 19
pos_gcview_end_vertex = 1 << 20
pos_command = 1 << 18
pos_gcview_end_vertex = 1 << 19
cdef inline uint32_t has_var(uint32_t status, uint32_t pos):
return status & pos
......@@ -60,11 +59,10 @@ cdef inline uint32_t set_has_var(uint32_t status, uint32_t pos):
cdef inline uint32_t unset_has_var(uint32_t status, uint32_t pos):
return status & ~pos
cdef class GLine(object):
cdef class GLine:
cdef char* _raw
cdef char* _command
cdef object _split_raw
cdef float _x, _y, _z, _e, _f, _i, _j, _s, _p
cdef float _current_x, _current_y, _current_z
cdef uint32_t _gcview_end_vertex
......@@ -78,6 +76,9 @@ cdef class GLine(object):
self._raw = NULL
self._command = NULL
def __init__(self, line):
self.raw = line
def __dealloc__(self):
if self._raw != NULL: free(self._raw)
if self._command != NULL: free(self._command)
......@@ -208,15 +209,6 @@ cdef class GLine(object):
def __set__(self, value):
self._gcview_end_vertex = value
self._status = set_has_var(self._status, pos_gcview_end_vertex)
property split_raw:
def __get__(self):
if has_var(self._status, pos_split_raw): return self._split_raw
else: return None
def __set__(self, value):
self._split_raw = value
self._status = set_has_var(self._status, pos_split_raw)
def __del__(self):
self._split_raw = None
property raw:
def __get__(self):
if has_var(self._status, pos_raw): return self._raw
......
......@@ -367,7 +367,8 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def sentcb(self, line):
gline = gcoder.Line(line)
gline.parse_coordinates(imperial = False)
split_raw = gcoder.split_line(gline)
gcoder.parse_coordinates(gline, split_raw, imperial = False)
if gline.is_move:
if gline.z != None:
layer = gline.z
......@@ -376,13 +377,13 @@ class PronterWindow(MainWindow, pronsole.pronsole):
self.gviz.clearhilights()
wx.CallAfter(self.gviz.setlayer, layer)
elif gline.command in ["M104", "M109"]:
gline.parse_coordinates(imperial = False, force = True)
gcoder.parse_coordinates(gline, split_raw, imperial = False, force = True)
if gline.s != None:
temp = gline.s
if self.display_gauges: wx.CallAfter(self.hottgauge.SetTarget, temp)
if self.display_graph: wx.CallAfter(self.graph.SetExtruder0TargetTemperature, temp)
elif gline.command == "M140":
gline.parse_coordinates(imperial = False, force = True)
gline.parse_coordinates(gline, split_raw, imperial = False, force = True)
if gline.s != None:
temp = gline.s
if self.display_gauges: wx.CallAfter(self.bedtgauge.SetTarget, temp)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment