Skip to content
Snippets Groups Projects
Commit 4eeb7920 authored by Oscar Gustafsson's avatar Oscar Gustafsson :bicyclist:
Browse files

Fix moving operations in y-direction

parent 47a0cefd
No related branches found
No related tags found
1 merge request!221Fix moving operations in y-direction
Pipeline #90241 passed
...@@ -31,7 +31,7 @@ from b_asic._preferences import ( ...@@ -31,7 +31,7 @@ from b_asic._preferences import (
from b_asic.graph_component import GraphID from b_asic.graph_component import GraphID
from b_asic.operation import Operation from b_asic.operation import Operation
from b_asic.port import InputPort, OutputPort from b_asic.port import InputPort, OutputPort
from b_asic.process import MemoryVariable, Process from b_asic.process import MemoryVariable
from b_asic.resources import ProcessCollection from b_asic.resources import ProcessCollection
from b_asic.signal_flow_graph import SFG from b_asic.signal_flow_graph import SFG
from b_asic.special_operations import Delay, Input, Output from b_asic.special_operations import Delay, Input, Output
...@@ -244,6 +244,7 @@ class Schedule: ...@@ -244,6 +244,7 @@ class Schedule:
return self.backward_slack(graph_id), self.forward_slack(graph_id) return self.backward_slack(graph_id), self.forward_slack(graph_id)
def print_slacks(self) -> None: def print_slacks(self) -> None:
"""Print the slack times for all operations in the schedule."""
raise NotImplementedError raise NotImplementedError
def set_schedule_time(self, time: int) -> "Schedule": def set_schedule_time(self, time: int) -> "Schedule":
...@@ -281,10 +282,12 @@ class Schedule: ...@@ -281,10 +282,12 @@ class Schedule:
@property @property
def schedule_time(self) -> int: def schedule_time(self) -> int:
"""The schedule time of the current schedule."""
return self._schedule_time return self._schedule_time
@property @property
def cyclic(self) -> bool: def cyclic(self) -> bool:
"""If the current schedule is cyclic."""
return self._cyclic return self._cyclic
def increase_time_resolution(self, factor: int) -> "Schedule": def increase_time_resolution(self, factor: int) -> "Schedule":
...@@ -360,6 +363,75 @@ class Schedule: ...@@ -360,6 +363,75 @@ class Schedule:
self._schedule_time = self._schedule_time // factor self._schedule_time = self._schedule_time // factor
return self return self
def move_y_location(
self, graph_id: GraphID, new_y: int, insert: bool = False
) -> None:
"""
Move operation in y-direction and remove any empty rows.
Parameters
----------
graph_id : GraphID
The GraphID of the operation to move.
new_y : int
The new y-position of the operation.
insert : bool, optional
If True, all operations on that y-position will be moved one position.
The default is False.
"""
if insert:
for gid, y_location in self._y_locations.items():
if y_location >= new_y:
self._y_locations[gid] += 1
self._y_locations[graph_id] = new_y
used_locations = {*self._y_locations.values()}
possible_locations = set(range(max(used_locations) + 1))
if not possible_locations - used_locations:
return
remapping = {}
offset = 0
for loc in possible_locations:
if loc in used_locations:
remapping[loc] = loc - offset
else:
offset += 1
for gid, y_location in self._y_locations.items():
self._y_locations[gid] = remapping[self._y_locations[gid]]
def get_y_location(self, graph_id: GraphID) -> int:
"""
Get the y-position of the Operation with GraphID *graph_id*.
Parameters
----------
graph_id : GraphID
The GraphID of the operation.
Returns
-------
int
The y-position of the operation.
"""
return self._y_locations[graph_id]
def set_y_location(self, graph_id: GraphID, y_location: int) -> None:
"""
Set the y-position of the Operation with GraphID *graph_id* to *y_location*.
Parameters
----------
graph_id : GraphID
The GraphID of the operation to move.
y_location : int
The new y-position of the operation.
"""
self._y_locations[graph_id] = y_location
def move_operation(self, graph_id: GraphID, time: int) -> "Schedule": def move_operation(self, graph_id: GraphID, time: int) -> "Schedule":
""" """
Move an operation in the schedule. Move an operation in the schedule.
......
...@@ -482,9 +482,13 @@ class MainWindow(QMainWindow, Ui_MainWindow): ...@@ -482,9 +482,13 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self._graph._signals.schedule_time_changed.connect( self._graph._signals.schedule_time_changed.connect(
self.info_table_update_schedule self.info_table_update_schedule
) )
self._graph._signals.redraw_all.connect(self._redraw_all)
self.info_table_fill_schedule(self._schedule) self.info_table_fill_schedule(self._schedule)
self.update_statusbar(self.tr("Schedule loaded successfully")) self.update_statusbar(self.tr("Schedule loaded successfully"))
def _redraw_all(self) -> None:
self._graph._redraw_all()
def update_statusbar(self, msg: str) -> None: def update_statusbar(self, msg: str) -> None:
""" """
Write *msg* to the statusbar with temporarily policy. Write *msg* to the statusbar with temporarily policy.
......
...@@ -44,12 +44,14 @@ class SchedulerEvent: # PyQt5 ...@@ -44,12 +44,14 @@ class SchedulerEvent: # PyQt5
component_selected = Signal(str) component_selected = Signal(str)
schedule_time_changed = Signal() schedule_time_changed = Signal()
component_moved = Signal(str) component_moved = Signal(str)
redraw_all = Signal()
_axes: Optional[AxesItem] _axes: Optional[AxesItem]
_current_pos: QPointF _current_pos: QPointF
_delta_time: int _delta_time: int
_signals: Signals # PyQt5 _signals: Signals # PyQt5
_schedule: Schedule _schedule: Schedule
_old_op_position: int = -1
def __init__(self, parent: Optional[QGraphicsItem] = None): # PyQt5 def __init__(self, parent: Optional[QGraphicsItem] = None): # PyQt5
super().__init__(parent=parent) super().__init__(parent=parent)
...@@ -202,7 +204,10 @@ class SchedulerEvent: # PyQt5 ...@@ -202,7 +204,10 @@ class SchedulerEvent: # PyQt5
self._current_pos.setX(self._current_pos.x() + dx) self._current_pos.setX(self._current_pos.x() + dx)
self._current_pos.setY(self._current_pos.y() + dy) self._current_pos.setY(self._current_pos.y() + dy)
self._redraw_lines(operation_item) self._redraw_lines(operation_item)
self._schedule._y_locations[operation_item.operation.graph_id] += dy gid = operation_item.operation.graph_id
self._schedule.set_y_location(
gid, dy + self._schedule.get_y_location(gid)
)
item: OperationItem = self.scene().mouseGrabberItem() item: OperationItem = self.scene().mouseGrabberItem()
delta_x = (item.mapToParent(event.pos()) - self._current_pos).x() delta_x = (item.mapToParent(event.pos()) - self._current_pos).x()
...@@ -224,7 +229,7 @@ class SchedulerEvent: # PyQt5 ...@@ -224,7 +229,7 @@ class SchedulerEvent: # PyQt5
allows the item to receive future move, release and double-click events. allows the item to receive future move, release and double-click events.
""" """
item: OperationItem = self.scene().mouseGrabberItem() item: OperationItem = self.scene().mouseGrabberItem()
self._old_op_position = self._schedule._y_locations[item.operation.graph_id] self._old_op_position = self._schedule.get_y_location(item.operation.graph_id)
self._signals.component_selected.emit(item.graph_id) self._signals.component_selected.emit(item.graph_id)
self._current_pos = item.mapToParent(event.pos()) self._current_pos = item.mapToParent(event.pos())
self.set_item_active(item) self.set_item_active(item)
...@@ -243,18 +248,20 @@ class SchedulerEvent: # PyQt5 ...@@ -243,18 +248,20 @@ class SchedulerEvent: # PyQt5
if pos_x > self._schedule.schedule_time: if pos_x > self._schedule.schedule_time:
pos_x = pos_x % self._schedule.schedule_time pos_x = pos_x % self._schedule.schedule_time
redraw = True redraw = True
if self._schedule._y_locations[item.operation.graph_id] % 1: pos_y = self._schedule.get_y_location(item.operation.graph_id)
# TODO: move other operations # Check move in y-direction
self._schedule._y_locations[item.operation.graph_id] = math.ceil( if pos_y != self._old_op_position:
self._schedule._y_locations[item.operation.graph_id] self._schedule.move_y_location(
item.operation.graph_id,
math.ceil(pos_y),
(pos_y % 1) != 0,
) )
pos_y = item.y() + (OPERATION_GAP + OPERATION_HEIGHT) / 2 self._signals.redraw_all.emit()
item.setY(pos_y) # Operation has been moved in x-direction
redraw = True
if redraw: if redraw:
item.setX(pos_x) item.setX(pos_x)
self._redraw_lines(item) self._redraw_lines(item)
self._signals.component_moved.emit(item.graph_id) self._signals.component_moved.emit(item.graph_id)
def operation_mouseDoubleClickEvent(self, event: QGraphicsSceneMouseEvent) -> None: def operation_mouseDoubleClickEvent(self, event: QGraphicsSceneMouseEvent) -> None:
... ...
......
...@@ -224,15 +224,18 @@ class SchedulerItem(SchedulerEvent, QGraphicsItemGroup): # PySide2 / PyQt5 ...@@ -224,15 +224,18 @@ class SchedulerItem(SchedulerEvent, QGraphicsItemGroup): # PySide2 / PyQt5
def _redraw_from_start(self) -> None: def _redraw_from_start(self) -> None:
self.schedule._reset_y_locations() self.schedule._reset_y_locations()
for graph_id in { for graph_id in dict(
k: v sorted(self.schedule.start_times.items(), key=lambda item: item[1])
for k, v in sorted( ):
self.schedule.start_times.items(), key=lambda item: item[1]
)
}:
self._set_position(graph_id) self._set_position(graph_id)
self._redraw_all_lines() self._redraw_all_lines()
def _redraw_all(self) -> None:
for graph_id in self._operation_items:
self._set_position(graph_id)
self._redraw_all_lines()
self._update_axes()
def _update_axes(self, build=False) -> None: def _update_axes(self, build=False) -> None:
# build axes # build axes
schedule_time = self.schedule.schedule_time schedule_time = self.schedule.schedule_time
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment