Merge branch 'coretk' of https://github.com/coreemu/core into coretk
This commit is contained in:
commit
0372e43cc5
4 changed files with 130 additions and 13 deletions
|
@ -421,8 +421,8 @@ class CoreClient:
|
|||
mobility_configs = self.get_mobility_configs_proto()
|
||||
emane_model_configs = self.get_emane_model_configs_proto()
|
||||
hooks = list(self.hooks.values())
|
||||
service_configs = self.get_service_config_proto()
|
||||
file_configs = self.get_service_file_config_proto()
|
||||
service_configs = self.get_service_configs_proto()
|
||||
file_configs = self.get_service_file_configs_proto()
|
||||
if self.emane_config:
|
||||
emane_config = {x: self.emane_config[x].value for x in self.emane_config}
|
||||
else:
|
||||
|
@ -512,6 +512,11 @@ class CoreClient:
|
|||
:return: nothing
|
||||
"""
|
||||
try:
|
||||
if self.state != core_pb2.SessionState.RUNTIME:
|
||||
logging.debug(
|
||||
"session state not runtime, send session data to the daemon..."
|
||||
)
|
||||
self.send_data()
|
||||
response = self.client.save_xml(self.session_id, file_path)
|
||||
logging.info("saved xml(%s): %s", file_path, response)
|
||||
except grpc.RpcError as e:
|
||||
|
@ -586,6 +591,52 @@ class CoreClient:
|
|||
)
|
||||
logging.debug("create link: %s", response)
|
||||
|
||||
def send_data(self):
|
||||
"""
|
||||
send to daemon all session info, but don't start the session
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
self.create_nodes_and_links()
|
||||
for config_proto in self.get_wlan_configs_proto():
|
||||
self.client.set_wlan_config(
|
||||
self.session_id, config_proto.node_id, config_proto.config
|
||||
)
|
||||
for config_proto in self.get_mobility_configs_proto():
|
||||
self.client.set_mobility_config(
|
||||
self.session_id, config_proto.node_id, config_proto.config
|
||||
)
|
||||
for config_proto in self.get_service_configs_proto():
|
||||
self.client.set_node_service(
|
||||
self.session_id,
|
||||
config_proto.node_id,
|
||||
config_proto.service,
|
||||
config_proto.startup,
|
||||
config_proto.validate,
|
||||
config_proto.shutdown,
|
||||
)
|
||||
for config_proto in self.get_service_file_configs_proto():
|
||||
self.client.set_node_service_file(
|
||||
self.session_id,
|
||||
config_proto.node_id,
|
||||
config_proto.service,
|
||||
config_proto.file,
|
||||
config_proto.data,
|
||||
)
|
||||
for hook in self.hooks.values():
|
||||
self.client.add_hook(self.session_id, hook.state, hook.file, hook.data)
|
||||
for config_proto in self.get_emane_model_configs_proto():
|
||||
self.client.set_emane_model_config(
|
||||
self.session_id,
|
||||
config_proto.node_id,
|
||||
config_proto.model,
|
||||
config_proto.config,
|
||||
config_proto.interface_id,
|
||||
)
|
||||
if self.emane_config:
|
||||
config = {x: self.emane_config[x].value for x in self.emane_config}
|
||||
self.client.set_emane_config(self.session_id, config)
|
||||
|
||||
def close(self):
|
||||
"""
|
||||
Clean ups when done using grpc
|
||||
|
@ -762,7 +813,7 @@ class CoreClient:
|
|||
configs.append(config_proto)
|
||||
return configs
|
||||
|
||||
def get_service_config_proto(self):
|
||||
def get_service_configs_proto(self):
|
||||
configs = []
|
||||
for node_id, services in self.service_configs.items():
|
||||
for name, config in services.items():
|
||||
|
@ -776,7 +827,7 @@ class CoreClient:
|
|||
configs.append(config_proto)
|
||||
return configs
|
||||
|
||||
def get_service_file_config_proto(self):
|
||||
def get_service_file_configs_proto(self):
|
||||
configs = []
|
||||
for (node_id, file_configs) in self.file_configs.items():
|
||||
for service, file_config in file_configs.items():
|
||||
|
|
|
@ -11,7 +11,7 @@ from coretk.graph.enums import GraphMode, ScaleOption
|
|||
from coretk.graph.linkinfo import LinkInfo, Throughput
|
||||
from coretk.graph.node import CanvasNode
|
||||
from coretk.graph.shape import Shape
|
||||
from coretk.graph.shapeutils import is_draw_shape
|
||||
from coretk.graph.shapeutils import ShapeType, is_draw_shape
|
||||
from coretk.nodeutils import NodeUtils
|
||||
|
||||
SCROLL_BUFFER = 25
|
||||
|
@ -32,6 +32,7 @@ class CanvasGraph(tk.Canvas):
|
|||
self.mode = GraphMode.SELECT
|
||||
self.annotation_type = None
|
||||
self.selection = {}
|
||||
self.select_box = None
|
||||
self.selected = None
|
||||
self.node_draw = None
|
||||
self.context = None
|
||||
|
@ -137,6 +138,13 @@ class CanvasGraph(tk.Canvas):
|
|||
self.tag_lower(self.grid)
|
||||
|
||||
def add_wireless_edge(self, src, dst):
|
||||
"""
|
||||
add a wireless edge between 2 canvas nodes
|
||||
|
||||
:param CanvasNode src: source node
|
||||
:param CanvasNode dst: destination node
|
||||
:return: nothing
|
||||
"""
|
||||
token = tuple(sorted((src.id, dst.id)))
|
||||
x1, y1 = self.coords(src.id)
|
||||
x2, y2 = self.coords(dst.id)
|
||||
|
@ -249,6 +257,7 @@ class CanvasGraph(tk.Canvas):
|
|||
:param event: mouse event
|
||||
:return: nothing
|
||||
"""
|
||||
logging.debug("click release")
|
||||
if self.context:
|
||||
self.context.unpost()
|
||||
self.context = None
|
||||
|
@ -260,6 +269,19 @@ class CanvasGraph(tk.Canvas):
|
|||
shape = self.shapes[self.selected]
|
||||
shape.shape_complete(x, y)
|
||||
self.shape_drawing = False
|
||||
elif self.mode == GraphMode.SELECT:
|
||||
self.focus_set()
|
||||
if self.select_box:
|
||||
x0, y0, x1, y1 = self.coords(self.select_box.id)
|
||||
inside = [
|
||||
x
|
||||
for x in self.find_enclosed(x0, y0, x1, y1)
|
||||
if "node" in self.gettags(x) or "shape" in self.gettags(x)
|
||||
]
|
||||
for i in inside:
|
||||
self.select_object(i, True)
|
||||
self.select_box.disappear()
|
||||
self.select_box = None
|
||||
else:
|
||||
self.focus_set()
|
||||
self.selected = self.get_selected(event)
|
||||
|
@ -445,6 +467,10 @@ class CanvasGraph(tk.Canvas):
|
|||
self.select_object(node.id)
|
||||
self.selected = selected
|
||||
else:
|
||||
logging.debug("create selection box")
|
||||
if self.mode == GraphMode.SELECT:
|
||||
shape = Shape(self.app, self, ShapeType.RECTANGLE, x, y)
|
||||
self.select_box = shape
|
||||
self.clear_selection()
|
||||
|
||||
def ctrl_click(self, event):
|
||||
|
@ -486,14 +512,18 @@ class CanvasGraph(tk.Canvas):
|
|||
return
|
||||
|
||||
# move selected objects
|
||||
for selected_id in self.selection:
|
||||
if selected_id in self.shapes:
|
||||
shape = self.shapes[selected_id]
|
||||
shape.motion(x_offset, y_offset)
|
||||
if len(self.selection) > 0:
|
||||
for selected_id in self.selection:
|
||||
if selected_id in self.shapes:
|
||||
shape = self.shapes[selected_id]
|
||||
shape.motion(x_offset, y_offset)
|
||||
|
||||
if selected_id in self.nodes:
|
||||
node = self.nodes[selected_id]
|
||||
node.motion(x_offset, y_offset, update=self.core.is_runtime())
|
||||
if selected_id in self.nodes:
|
||||
node = self.nodes[selected_id]
|
||||
node.motion(x_offset, y_offset, update=self.core.is_runtime())
|
||||
else:
|
||||
if self.select_box and self.mode == GraphMode.SELECT:
|
||||
self.select_box.shape_motion(x, y)
|
||||
|
||||
def click_context(self, event):
|
||||
logging.info("context event: %s", self.context)
|
||||
|
@ -681,3 +711,23 @@ class CanvasGraph(tk.Canvas):
|
|||
|
||||
def is_selection_mode(self):
|
||||
return self.mode == GraphMode.SELECT
|
||||
|
||||
def create_edge(self, source, dest):
|
||||
"""
|
||||
create an edge between source node and destination node
|
||||
|
||||
:param CanvasNode source: source node
|
||||
:param CanvasNode dest: destination node
|
||||
:return: nothing
|
||||
"""
|
||||
if tuple([source.id, dest.id]) not in self.edges:
|
||||
pos0 = source.core_node.position
|
||||
x0 = pos0.x
|
||||
y0 = pos0.y
|
||||
edge = CanvasEdge(x0, y0, x0, y0, source.id, self)
|
||||
edge.complete(dest.id)
|
||||
self.edges[edge.token] = edge
|
||||
self.nodes[source.id].edges.add(edge)
|
||||
self.nodes[dest.id].edges.add(edge)
|
||||
link = self.core.create_link(edge, source, dest)
|
||||
edge.link_info = LinkInfo(self, edge, link)
|
||||
|
|
|
@ -3,6 +3,7 @@ from tkinter import font
|
|||
|
||||
import grpc
|
||||
|
||||
from core.api.grpc import core_pb2
|
||||
from core.api.grpc.core_pb2 import NodeType
|
||||
from coretk import themes
|
||||
from coretk.dialogs.emaneconfig import EmaneConfigDialog
|
||||
|
@ -193,7 +194,9 @@ class CanvasNode:
|
|||
label="Mobility Config", command=self.show_mobility_config
|
||||
)
|
||||
if NodeUtils.is_wireless_node(self.core_node.type):
|
||||
context.add_command(label="Link To All MDRs", state=tk.DISABLED)
|
||||
context.add_command(
|
||||
label="Link To Selected", command=self.wireless_link_selected
|
||||
)
|
||||
context.add_command(label="Select Members", state=tk.DISABLED)
|
||||
context.add_command(label="Select Adjacent", state=tk.DISABLED)
|
||||
context.add_command(label="Create Link To", state=tk.DISABLED)
|
||||
|
@ -235,3 +238,13 @@ class CanvasNode:
|
|||
self.canvas.context = None
|
||||
dialog = NodeService(self.app.master, self.app, self)
|
||||
dialog.show()
|
||||
|
||||
def wireless_link_selected(self):
|
||||
self.canvas.context = None
|
||||
for canvas_nid in [
|
||||
x for x in self.canvas.selection if "node" in self.canvas.gettags(x)
|
||||
]:
|
||||
core_node = self.canvas.nodes[canvas_nid].core_node
|
||||
if core_node.type == core_pb2.NodeType.DEFAULT and core_node.model == "mdr":
|
||||
self.canvas.create_edge(self, self.canvas.nodes[canvas_nid])
|
||||
self.canvas.clear_selection()
|
||||
|
|
|
@ -132,6 +132,9 @@ class Shape:
|
|||
s = ShapeDialog(self.app, self.app, self)
|
||||
s.show()
|
||||
|
||||
def disappear(self):
|
||||
self.canvas.delete(self.id)
|
||||
|
||||
def motion(self, x_offset, y_offset):
|
||||
self.canvas.move(self.id, x_offset, y_offset)
|
||||
self.canvas.move_selection(self.id, x_offset, y_offset)
|
||||
|
|
Loading…
Add table
Reference in a new issue