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()
|
mobility_configs = self.get_mobility_configs_proto()
|
||||||
emane_model_configs = self.get_emane_model_configs_proto()
|
emane_model_configs = self.get_emane_model_configs_proto()
|
||||||
hooks = list(self.hooks.values())
|
hooks = list(self.hooks.values())
|
||||||
service_configs = self.get_service_config_proto()
|
service_configs = self.get_service_configs_proto()
|
||||||
file_configs = self.get_service_file_config_proto()
|
file_configs = self.get_service_file_configs_proto()
|
||||||
if self.emane_config:
|
if self.emane_config:
|
||||||
emane_config = {x: self.emane_config[x].value for x in self.emane_config}
|
emane_config = {x: self.emane_config[x].value for x in self.emane_config}
|
||||||
else:
|
else:
|
||||||
|
@ -512,6 +512,11 @@ class CoreClient:
|
||||||
:return: nothing
|
:return: nothing
|
||||||
"""
|
"""
|
||||||
try:
|
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)
|
response = self.client.save_xml(self.session_id, file_path)
|
||||||
logging.info("saved xml(%s): %s", file_path, response)
|
logging.info("saved xml(%s): %s", file_path, response)
|
||||||
except grpc.RpcError as e:
|
except grpc.RpcError as e:
|
||||||
|
@ -586,6 +591,52 @@ class CoreClient:
|
||||||
)
|
)
|
||||||
logging.debug("create link: %s", response)
|
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):
|
def close(self):
|
||||||
"""
|
"""
|
||||||
Clean ups when done using grpc
|
Clean ups when done using grpc
|
||||||
|
@ -762,7 +813,7 @@ class CoreClient:
|
||||||
configs.append(config_proto)
|
configs.append(config_proto)
|
||||||
return configs
|
return configs
|
||||||
|
|
||||||
def get_service_config_proto(self):
|
def get_service_configs_proto(self):
|
||||||
configs = []
|
configs = []
|
||||||
for node_id, services in self.service_configs.items():
|
for node_id, services in self.service_configs.items():
|
||||||
for name, config in services.items():
|
for name, config in services.items():
|
||||||
|
@ -776,7 +827,7 @@ class CoreClient:
|
||||||
configs.append(config_proto)
|
configs.append(config_proto)
|
||||||
return configs
|
return configs
|
||||||
|
|
||||||
def get_service_file_config_proto(self):
|
def get_service_file_configs_proto(self):
|
||||||
configs = []
|
configs = []
|
||||||
for (node_id, file_configs) in self.file_configs.items():
|
for (node_id, file_configs) in self.file_configs.items():
|
||||||
for service, file_config in 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.linkinfo import LinkInfo, Throughput
|
||||||
from coretk.graph.node import CanvasNode
|
from coretk.graph.node import CanvasNode
|
||||||
from coretk.graph.shape import Shape
|
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
|
from coretk.nodeutils import NodeUtils
|
||||||
|
|
||||||
SCROLL_BUFFER = 25
|
SCROLL_BUFFER = 25
|
||||||
|
@ -32,6 +32,7 @@ class CanvasGraph(tk.Canvas):
|
||||||
self.mode = GraphMode.SELECT
|
self.mode = GraphMode.SELECT
|
||||||
self.annotation_type = None
|
self.annotation_type = None
|
||||||
self.selection = {}
|
self.selection = {}
|
||||||
|
self.select_box = None
|
||||||
self.selected = None
|
self.selected = None
|
||||||
self.node_draw = None
|
self.node_draw = None
|
||||||
self.context = None
|
self.context = None
|
||||||
|
@ -137,6 +138,13 @@ class CanvasGraph(tk.Canvas):
|
||||||
self.tag_lower(self.grid)
|
self.tag_lower(self.grid)
|
||||||
|
|
||||||
def add_wireless_edge(self, src, dst):
|
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)))
|
token = tuple(sorted((src.id, dst.id)))
|
||||||
x1, y1 = self.coords(src.id)
|
x1, y1 = self.coords(src.id)
|
||||||
x2, y2 = self.coords(dst.id)
|
x2, y2 = self.coords(dst.id)
|
||||||
|
@ -249,6 +257,7 @@ class CanvasGraph(tk.Canvas):
|
||||||
:param event: mouse event
|
:param event: mouse event
|
||||||
:return: nothing
|
:return: nothing
|
||||||
"""
|
"""
|
||||||
|
logging.debug("click release")
|
||||||
if self.context:
|
if self.context:
|
||||||
self.context.unpost()
|
self.context.unpost()
|
||||||
self.context = None
|
self.context = None
|
||||||
|
@ -260,6 +269,19 @@ class CanvasGraph(tk.Canvas):
|
||||||
shape = self.shapes[self.selected]
|
shape = self.shapes[self.selected]
|
||||||
shape.shape_complete(x, y)
|
shape.shape_complete(x, y)
|
||||||
self.shape_drawing = False
|
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:
|
else:
|
||||||
self.focus_set()
|
self.focus_set()
|
||||||
self.selected = self.get_selected(event)
|
self.selected = self.get_selected(event)
|
||||||
|
@ -445,6 +467,10 @@ class CanvasGraph(tk.Canvas):
|
||||||
self.select_object(node.id)
|
self.select_object(node.id)
|
||||||
self.selected = selected
|
self.selected = selected
|
||||||
else:
|
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()
|
self.clear_selection()
|
||||||
|
|
||||||
def ctrl_click(self, event):
|
def ctrl_click(self, event):
|
||||||
|
@ -486,14 +512,18 @@ class CanvasGraph(tk.Canvas):
|
||||||
return
|
return
|
||||||
|
|
||||||
# move selected objects
|
# move selected objects
|
||||||
for selected_id in self.selection:
|
if len(self.selection) > 0:
|
||||||
if selected_id in self.shapes:
|
for selected_id in self.selection:
|
||||||
shape = self.shapes[selected_id]
|
if selected_id in self.shapes:
|
||||||
shape.motion(x_offset, y_offset)
|
shape = self.shapes[selected_id]
|
||||||
|
shape.motion(x_offset, y_offset)
|
||||||
|
|
||||||
if selected_id in self.nodes:
|
if selected_id in self.nodes:
|
||||||
node = self.nodes[selected_id]
|
node = self.nodes[selected_id]
|
||||||
node.motion(x_offset, y_offset, update=self.core.is_runtime())
|
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):
|
def click_context(self, event):
|
||||||
logging.info("context event: %s", self.context)
|
logging.info("context event: %s", self.context)
|
||||||
|
@ -681,3 +711,23 @@ class CanvasGraph(tk.Canvas):
|
||||||
|
|
||||||
def is_selection_mode(self):
|
def is_selection_mode(self):
|
||||||
return self.mode == GraphMode.SELECT
|
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
|
import grpc
|
||||||
|
|
||||||
|
from core.api.grpc import core_pb2
|
||||||
from core.api.grpc.core_pb2 import NodeType
|
from core.api.grpc.core_pb2 import NodeType
|
||||||
from coretk import themes
|
from coretk import themes
|
||||||
from coretk.dialogs.emaneconfig import EmaneConfigDialog
|
from coretk.dialogs.emaneconfig import EmaneConfigDialog
|
||||||
|
@ -193,7 +194,9 @@ class CanvasNode:
|
||||||
label="Mobility Config", command=self.show_mobility_config
|
label="Mobility Config", command=self.show_mobility_config
|
||||||
)
|
)
|
||||||
if NodeUtils.is_wireless_node(self.core_node.type):
|
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 Members", state=tk.DISABLED)
|
||||||
context.add_command(label="Select Adjacent", state=tk.DISABLED)
|
context.add_command(label="Select Adjacent", state=tk.DISABLED)
|
||||||
context.add_command(label="Create Link To", state=tk.DISABLED)
|
context.add_command(label="Create Link To", state=tk.DISABLED)
|
||||||
|
@ -235,3 +238,13 @@ class CanvasNode:
|
||||||
self.canvas.context = None
|
self.canvas.context = None
|
||||||
dialog = NodeService(self.app.master, self.app, self)
|
dialog = NodeService(self.app.master, self.app, self)
|
||||||
dialog.show()
|
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 = ShapeDialog(self.app, self.app, self)
|
||||||
s.show()
|
s.show()
|
||||||
|
|
||||||
|
def disappear(self):
|
||||||
|
self.canvas.delete(self.id)
|
||||||
|
|
||||||
def motion(self, x_offset, y_offset):
|
def motion(self, x_offset, y_offset):
|
||||||
self.canvas.move(self.id, x_offset, y_offset)
|
self.canvas.move(self.id, x_offset, y_offset)
|
||||||
self.canvas.move_selection(self.id, x_offset, y_offset)
|
self.canvas.move_selection(self.id, x_offset, y_offset)
|
||||||
|
|
Loading…
Add table
Reference in a new issue