From 874e8ac0d90dc1a5bd98a6078bc980562e0f3da8 Mon Sep 17 00:00:00 2001 From: krande Date: Sun, 29 Sep 2024 16:29:32 +0200 Subject: [PATCH] further work --- .../list_server_file_objects.py | 16 ++- .../procedures/add_stiffeners.py | 4 +- src/ada/comms/exceptions.py | 2 + src/ada/comms/fb_deserializer.py | 103 ++++++++++++------ src/ada/comms/fb_model_gen.py | 26 ++++- src/ada/comms/fb_serializer.py | 36 +++++- .../comms/msg_handling/default_on_message.py | 36 +++--- .../comms/msg_handling/list_file_objects.py | 31 ++++++ src/ada/comms/msg_handling/list_procedures.py | 3 +- .../comms/msg_handling/mesh_info_callback.py | 6 +- src/ada/comms/msg_handling/on_error_reply.py | 23 ++++ src/ada/comms/msg_handling/update_scene.py | 4 +- src/ada/comms/msg_handling/update_server.py | 3 +- src/ada/comms/wsock/CameraParams.py | 41 ++++++- src/ada/comms/wsock/CommandType.py | 1 + src/ada/comms/wsock/Error.py | 13 ++- src/ada/comms/wsock/FileObject.py | 25 ++++- src/ada/comms/wsock/FilePurpose.py | 1 + src/ada/comms/wsock/FileType.py | 1 + src/ada/comms/wsock/MeshInfo.py | 15 ++- src/ada/comms/wsock/Message.py | 39 ++++++- src/ada/comms/wsock/Parameter.py | 15 ++- src/ada/comms/wsock/Procedure.py | 28 ++++- src/ada/comms/wsock/ProcedureStart.py | 16 ++- src/ada/comms/wsock/ProcedureState.py | 1 + src/ada/comms/wsock/ProcedureStore.py | 17 ++- src/ada/comms/wsock/Scene.py | 17 ++- src/ada/comms/wsock/SceneOperations.py | 1 + src/ada/comms/wsock/Server.py | 17 ++- src/ada/comms/wsock/ServerReply.py | 16 ++- src/ada/comms/wsock/TargetType.py | 1 + src/ada/comms/wsock/WebClient.py | 17 ++- src/ada/comms/wsock_client_async.py | 10 +- src/ada/comms/wsock_client_base.py | 11 +- src/ada/comms/wsock_client_sync.py | 5 + src/ada/comms/wsock_server.py | 4 +- .../node_editor/NodeEditorComponent.tsx | 21 +++- .../fb_handling/handle_incoming_buffers.ts | 6 +- ...procedures.ts => request_list_of_nodes.ts} | 2 +- .../src/utils/node_editor/run_sequence.ts | 3 + ..._list_of_procedures.ts => update_nodes.ts} | 30 ++++- tests/core/comms/test_buffers.py | 14 +-- 42 files changed, 573 insertions(+), 108 deletions(-) create mode 100644 src/ada/comms/exceptions.py create mode 100644 src/ada/comms/msg_handling/list_file_objects.py create mode 100644 src/ada/comms/msg_handling/on_error_reply.py rename src/frontend/src/utils/node_editor/{request_list_of_procedures.ts => request_list_of_nodes.ts} (93%) create mode 100644 src/frontend/src/utils/node_editor/run_sequence.ts rename src/frontend/src/utils/node_editor/{update_list_of_procedures.ts => update_nodes.ts} (59%) diff --git a/examples/procedure_example/list_server_file_objects.py b/examples/procedure_example/list_server_file_objects.py index ce2ac5f69..dec812e8c 100644 --- a/examples/procedure_example/list_server_file_objects.py +++ b/examples/procedure_example/list_server_file_objects.py @@ -1,7 +1,13 @@ import asyncio import pathlib -from ada.comms.fb_model_gen import ParameterDC, ProcedureStartDC +from ada.comms.fb_model_gen import ( + FileObjectDC, + FilePurposeDC, + FileTypeDC, + ParameterDC, + ProcedureStartDC, +) from ada.comms.wsock_client_async import WebSocketClientAsync THIS_DIR = pathlib.Path(__file__).parent @@ -10,11 +16,11 @@ async def list_procedures(): async with WebSocketClientAsync("localhost", 8765, "local") as ws_client: - procedures = await ws_client.list_procedures() - await ws_client.run_procedure( - ProcedureStartDC("add_stiffeners", [ParameterDC(name="ifc_file", value="MyBaseStructure.ifc")]) + await ws_client.update_file_server( + FileObjectDC("test_file", FileTypeDC.IFC, FilePurposeDC.DESIGN, THIS_DIR / "temp/MyBaseStructure.ifc") ) - print(procedures) + file_objects = await ws_client.list_server_file_objects() + print(file_objects) if __name__ == "__main__": diff --git a/examples/procedure_example/procedures/add_stiffeners.py b/examples/procedure_example/procedures/add_stiffeners.py index 0f24c78a1..9af91109f 100644 --- a/examples/procedure_example/procedures/add_stiffeners.py +++ b/examples/procedure_example/procedures/add_stiffeners.py @@ -2,11 +2,11 @@ import numpy as np import typer +from typing_extensions import Annotated import ada from ada.comms.fb_model_gen import FileTypeDC from ada.comms.procedures import procedure_decorator -from typing_extensions import Annotated app = typer.Typer() THIS_FILE = pathlib.Path(__file__).resolve().absolute() @@ -48,7 +48,7 @@ def add_stiffeners(pl: ada.Plate) -> list[ada.Beam]: @procedure_decorator(app, input_file_var="ifc_file", input_file_type=FileTypeDC.IFC, export_file_type=FileTypeDC.IFC) -def main(ifc_file: pathlib.Path=None) -> pathlib.Path: +def main(ifc_file: pathlib.Path = None) -> pathlib.Path: """A procedure to add stiffeners to all plates in the IFC file""" a = ada.from_ifc(ifc_file) diff --git a/src/ada/comms/exceptions.py b/src/ada/comms/exceptions.py new file mode 100644 index 000000000..8c3951c65 --- /dev/null +++ b/src/ada/comms/exceptions.py @@ -0,0 +1,2 @@ +class ServerError(Exception): + pass diff --git a/src/ada/comms/fb_deserializer.py b/src/ada/comms/fb_deserializer.py index 80a56ce88..e8479efeb 100644 --- a/src/ada/comms/fb_deserializer.py +++ b/src/ada/comms/fb_deserializer.py @@ -1,6 +1,26 @@ +from ada.comms.fb_model_gen import ( + CameraParamsDC, + CommandTypeDC, + ErrorDC, + FileObjectDC, + FilePurposeDC, + FileTypeDC, + MeshInfoDC, + MessageDC, + ParameterDC, + ProcedureDC, + ProcedureStartDC, + ProcedureStateDC, + ProcedureStoreDC, + SceneDC, + SceneOperationsDC, + ServerDC, + ServerReplyDC, + TargetTypeDC, + WebClientDC, +) from ada.comms.wsock import Message -from ada.comms.fb_model_gen import WebClientDC, FileObjectDC, MeshInfoDC, CameraParamsDC, SceneDC, ServerDC, ProcedureStoreDC, ProcedureDC, ParameterDC, ProcedureStartDC, ErrorDC, ServerReplyDC, MessageDC,CommandTypeDC, TargetTypeDC, SceneOperationsDC, FilePurposeDC, FileTypeDC, ProcedureStateDC def deserialize_webclient(fb_obj) -> WebClientDC | None: if fb_obj is None: @@ -8,9 +28,9 @@ def deserialize_webclient(fb_obj) -> WebClientDC | None: return WebClientDC( instance_id=fb_obj.InstanceId(), - name=fb_obj.Name().decode('utf-8') if fb_obj.Name() is not None else None, - address=fb_obj.Address().decode('utf-8') if fb_obj.Address() is not None else None, - port=fb_obj.Port() + name=fb_obj.Name().decode("utf-8") if fb_obj.Name() is not None else None, + address=fb_obj.Address().decode("utf-8") if fb_obj.Address() is not None else None, + port=fb_obj.Port(), ) @@ -19,11 +39,11 @@ def deserialize_fileobject(fb_obj) -> FileObjectDC | None: return None return FileObjectDC( - name=fb_obj.Name().decode('utf-8') if fb_obj.Name() is not None else None, + name=fb_obj.Name().decode("utf-8") if fb_obj.Name() is not None else None, file_type=FileTypeDC(fb_obj.FileType()), purpose=FilePurposeDC(fb_obj.Purpose()), - filepath=fb_obj.Filepath().decode('utf-8') if fb_obj.Filepath() is not None else None, - filedata=bytes(fb_obj.FiledataAsNumpy()) if fb_obj.FiledataLength() > 0 else None + filepath=fb_obj.Filepath().decode("utf-8") if fb_obj.Filepath() is not None else None, + filedata=bytes(fb_obj.FiledataAsNumpy()) if fb_obj.FiledataLength() > 0 else None, ) @@ -32,9 +52,9 @@ def deserialize_meshinfo(fb_obj) -> MeshInfoDC | None: return None return MeshInfoDC( - object_name=fb_obj.ObjectName().decode('utf-8') if fb_obj.ObjectName() is not None else None, + object_name=fb_obj.ObjectName().decode("utf-8") if fb_obj.ObjectName() is not None else None, face_index=fb_obj.FaceIndex(), - json_data=fb_obj.JsonData().decode('utf-8') if fb_obj.JsonData() is not None else None + json_data=fb_obj.JsonData().decode("utf-8") if fb_obj.JsonData() is not None else None, ) @@ -49,7 +69,7 @@ def deserialize_cameraparams(fb_obj) -> CameraParamsDC | None: fov=fb_obj.Fov(), near=fb_obj.Near(), far=fb_obj.Far(), - force_camera=fb_obj.ForceCamera() + force_camera=fb_obj.ForceCamera(), ) @@ -60,7 +80,7 @@ def deserialize_scene(fb_obj) -> SceneDC | None: return SceneDC( operation=SceneOperationsDC(fb_obj.Operation()), camera_params=deserialize_cameraparams(fb_obj.CameraParams()), - current_file=deserialize_fileobject(fb_obj.CurrentFile()) + current_file=deserialize_fileobject(fb_obj.CurrentFile()), ) @@ -70,7 +90,11 @@ def deserialize_server(fb_obj) -> ServerDC | None: return ServerDC( add_file_object=deserialize_fileobject(fb_obj.AddFileObject()), - all_file_objects=[deserialize_fileobject(fb_obj.AllFileObjects(i)) for i in range(fb_obj.AllFileObjectsLength())] if fb_obj.AllFileObjectsLength() > 0 else None + all_file_objects=( + [deserialize_fileobject(fb_obj.AllFileObjects(i)) for i in range(fb_obj.AllFileObjectsLength())] + if fb_obj.AllFileObjectsLength() > 0 + else None + ), ) @@ -79,8 +103,12 @@ def deserialize_procedurestore(fb_obj) -> ProcedureStoreDC | None: return None return ProcedureStoreDC( - procedures=[deserialize_procedure(fb_obj.Procedures(i)) for i in range(fb_obj.ProceduresLength())] if fb_obj.ProceduresLength() > 0 else None, - start_procedure=deserialize_procedurestart(fb_obj.StartProcedure()) + procedures=( + [deserialize_procedure(fb_obj.Procedures(i)) for i in range(fb_obj.ProceduresLength())] + if fb_obj.ProceduresLength() > 0 + else None + ), + start_procedure=deserialize_procedurestart(fb_obj.StartProcedure()), ) @@ -89,14 +117,20 @@ def deserialize_procedure(fb_obj) -> ProcedureDC | None: return None return ProcedureDC( - name=fb_obj.Name().decode('utf-8') if fb_obj.Name() is not None else None, - description=fb_obj.Description().decode('utf-8') if fb_obj.Description() is not None else None, - script_file_location=fb_obj.ScriptFileLocation().decode('utf-8') if fb_obj.ScriptFileLocation() is not None else None, - parameters=[deserialize_parameter(fb_obj.Parameters(i)) for i in range(fb_obj.ParametersLength())] if fb_obj.ParametersLength() > 0 else None, - input_file_var=fb_obj.InputFileVar().decode('utf-8') if fb_obj.InputFileVar() is not None else None, + name=fb_obj.Name().decode("utf-8") if fb_obj.Name() is not None else None, + description=fb_obj.Description().decode("utf-8") if fb_obj.Description() is not None else None, + script_file_location=( + fb_obj.ScriptFileLocation().decode("utf-8") if fb_obj.ScriptFileLocation() is not None else None + ), + parameters=( + [deserialize_parameter(fb_obj.Parameters(i)) for i in range(fb_obj.ParametersLength())] + if fb_obj.ParametersLength() > 0 + else None + ), + input_file_var=fb_obj.InputFileVar().decode("utf-8") if fb_obj.InputFileVar() is not None else None, input_file_type=FileTypeDC(fb_obj.InputFileType()), export_file_type=FileTypeDC(fb_obj.ExportFileType()), - state=ProcedureStateDC(fb_obj.State()) + state=ProcedureStateDC(fb_obj.State()), ) @@ -105,9 +139,9 @@ def deserialize_parameter(fb_obj) -> ParameterDC | None: return None return ParameterDC( - name=fb_obj.Name().decode('utf-8') if fb_obj.Name() is not None else None, - type=fb_obj.Type().decode('utf-8') if fb_obj.Type() is not None else None, - value=fb_obj.Value().decode('utf-8') if fb_obj.Value() is not None else None + name=fb_obj.Name().decode("utf-8") if fb_obj.Name() is not None else None, + type=fb_obj.Type().decode("utf-8") if fb_obj.Type() is not None else None, + value=fb_obj.Value().decode("utf-8") if fb_obj.Value() is not None else None, ) @@ -116,8 +150,12 @@ def deserialize_procedurestart(fb_obj) -> ProcedureStartDC | None: return None return ProcedureStartDC( - procedure_name=fb_obj.ProcedureName().decode('utf-8') if fb_obj.ProcedureName() is not None else None, - parameters=[deserialize_parameter(fb_obj.Parameters(i)) for i in range(fb_obj.ParametersLength())] if fb_obj.ParametersLength() > 0 else None + procedure_name=fb_obj.ProcedureName().decode("utf-8") if fb_obj.ProcedureName() is not None else None, + parameters=( + [deserialize_parameter(fb_obj.Parameters(i)) for i in range(fb_obj.ParametersLength())] + if fb_obj.ParametersLength() > 0 + else None + ), ) @@ -126,8 +164,7 @@ def deserialize_error(fb_obj) -> ErrorDC | None: return None return ErrorDC( - code=fb_obj.Code(), - message=fb_obj.Message().decode('utf-8') if fb_obj.Message() is not None else None + code=fb_obj.Code(), message=fb_obj.Message().decode("utf-8") if fb_obj.Message() is not None else None ) @@ -136,9 +173,9 @@ def deserialize_serverreply(fb_obj) -> ServerReplyDC | None: return None return ServerReplyDC( - message=fb_obj.Message().decode('utf-8') if fb_obj.Message() is not None else None, + message=fb_obj.Message().decode("utf-8") if fb_obj.Message() is not None else None, reply_to=CommandTypeDC(fb_obj.ReplyTo()), - error=deserialize_error(fb_obj.Error()) + error=deserialize_error(fb_obj.Error()), ) @@ -155,9 +192,13 @@ def deserialize_message(fb_obj) -> MessageDC | None: target_group=TargetTypeDC(fb_obj.TargetGroup()), client_type=TargetTypeDC(fb_obj.ClientType()), target_id=fb_obj.TargetId(), - web_clients=[deserialize_webclient(fb_obj.WebClients(i)) for i in range(fb_obj.WebClientsLength())] if fb_obj.WebClientsLength() > 0 else None, + web_clients=( + [deserialize_webclient(fb_obj.WebClients(i)) for i in range(fb_obj.WebClientsLength())] + if fb_obj.WebClientsLength() > 0 + else None + ), procedure_store=deserialize_procedurestore(fb_obj.ProcedureStore()), - server_reply=deserialize_serverreply(fb_obj.ServerReply()) + server_reply=deserialize_serverreply(fb_obj.ServerReply()), ) diff --git a/src/ada/comms/fb_model_gen.py b/src/ada/comms/fb_model_gen.py index b00928894..da63623ab 100644 --- a/src/ada/comms/fb_model_gen.py +++ b/src/ada/comms/fb_model_gen.py @@ -1,9 +1,9 @@ from __future__ import annotations -from enum import Enum -from dataclasses import dataclass -from typing import Optional, List -import pathlib +import pathlib +from dataclasses import dataclass +from enum import Enum +from typing import List, Optional class CommandTypeDC(Enum): @@ -20,32 +20,38 @@ class CommandTypeDC(Enum): ERROR = 10 SERVER_REPLY = 11 + class TargetTypeDC(Enum): WEB = 0 LOCAL = 1 SERVER = 2 + class SceneOperationsDC(Enum): ADD = 0 REMOVE = 1 REPLACE = 2 + class FilePurposeDC(Enum): DESIGN = 0 ANALYSIS = 1 FABRICATE = 2 + class FileTypeDC(Enum): IFC = 0 GLB = 1 SQLITE = 2 + class ProcedureStateDC(Enum): IDLE = 0 RUNNING = 1 FINISHED = 2 ERROR = 3 + @dataclass class WebClientDC: instance_id: int = None @@ -53,6 +59,7 @@ class WebClientDC: address: str = "" port: int = None + @dataclass class FileObjectDC: name: str = "" @@ -61,12 +68,14 @@ class FileObjectDC: filepath: pathlib.Path | str = "" filedata: bytes = None + @dataclass class MeshInfoDC: object_name: str = "" face_index: int = None json_data: str = "" + @dataclass class CameraParamsDC: position: List[float] = None @@ -77,22 +86,26 @@ class CameraParamsDC: far: float = None force_camera: bool = None + @dataclass class SceneDC: operation: Optional[SceneOperationsDC] = None camera_params: Optional[CameraParamsDC] = None current_file: Optional[FileObjectDC] = None + @dataclass class ServerDC: add_file_object: Optional[FileObjectDC] = None all_file_objects: Optional[List[FileObjectDC]] = None + @dataclass class ProcedureStoreDC: procedures: Optional[List[ProcedureDC]] = None start_procedure: Optional[ProcedureStartDC] = None + @dataclass class ProcedureDC: name: str = "" @@ -104,28 +117,33 @@ class ProcedureDC: export_file_type: Optional[FileTypeDC] = None state: Optional[ProcedureStateDC] = None + @dataclass class ParameterDC: name: str = "" type: str = "" value: str = "" + @dataclass class ProcedureStartDC: procedure_name: str = "" parameters: Optional[List[ParameterDC]] = None + @dataclass class ErrorDC: code: int = None message: str = "" + @dataclass class ServerReplyDC: message: str = "" reply_to: Optional[CommandTypeDC] = None error: Optional[ErrorDC] = None + @dataclass class MessageDC: instance_id: int = None diff --git a/src/ada/comms/fb_serializer.py b/src/ada/comms/fb_serializer.py index fc1fd9127..a886f2c9a 100644 --- a/src/ada/comms/fb_serializer.py +++ b/src/ada/comms/fb_serializer.py @@ -1,9 +1,37 @@ -import flatbuffers from typing import Optional -from ada.comms.wsock import WebClient, FileObject, MeshInfo, CameraParams, Scene, Server, ProcedureStore, Procedure, Parameter, ProcedureStart, Error, ServerReply, Message +import flatbuffers +from ada.comms.fb_model_gen import ( + CameraParamsDC, + ErrorDC, + FileObjectDC, + MeshInfoDC, + MessageDC, + ParameterDC, + ProcedureDC, + ProcedureStartDC, + ProcedureStoreDC, + SceneDC, + ServerDC, + ServerReplyDC, + WebClientDC, +) +from ada.comms.wsock import ( + CameraParams, + Error, + FileObject, + MeshInfo, + Message, + Parameter, + Procedure, + ProcedureStart, + ProcedureStore, + Scene, + Server, + ServerReply, + WebClient, +) -from ada.comms.fb_model_gen import WebClientDC, FileObjectDC, MeshInfoDC, CameraParamsDC, SceneDC, ServerDC, ProcedureStoreDC, ProcedureDC, ParameterDC, ProcedureStartDC, ErrorDC, ServerReplyDC, MessageDC def serialize_webclient(builder: flatbuffers.Builder, obj: Optional[WebClientDC]) -> Optional[int]: if obj is None: @@ -283,7 +311,7 @@ def serialize_serverreply(builder: flatbuffers.Builder, obj: Optional[ServerRepl return ServerReply.End(builder) -def serialize_message(message: MessageDC, builder: flatbuffers.Builder=None) -> bytes: +def serialize_message(message: MessageDC, builder: flatbuffers.Builder = None) -> bytes: if builder is None: builder = flatbuffers.Builder(1024) scene_obj = None diff --git a/src/ada/comms/msg_handling/default_on_message.py b/src/ada/comms/msg_handling/default_on_message.py index 66d029ab1..5f9f26933 100644 --- a/src/ada/comms/msg_handling/default_on_message.py +++ b/src/ada/comms/msg_handling/default_on_message.py @@ -4,8 +4,10 @@ from ada.comms.fb_deserializer import deserialize_root_message from ada.comms.fb_model_gen import CommandTypeDC +from ada.comms.msg_handling.list_file_objects import list_file_objects from ada.comms.msg_handling.list_procedures import list_procedures from ada.comms.msg_handling.mesh_info_callback import mesh_info_callback +from ada.comms.msg_handling.on_error_reply import on_error_reply from ada.comms.msg_handling.run_procedure import run_procedure from ada.comms.msg_handling.update_scene import update_scene from ada.comms.msg_handling.update_server import update_server @@ -16,16 +18,24 @@ def default_on_message(server: WebSocketAsyncServer, client: ConnectedClient, message_data: bytes) -> None: - message = deserialize_root_message(message_data) - if message.command_type == CommandTypeDC.UPDATE_SCENE: - update_scene(server, client, message) - elif message.command_type == CommandTypeDC.UPDATE_SERVER: - update_server(server, client, message) - elif message.command_type == CommandTypeDC.MESH_INFO_CALLBACK: - mesh_info_callback(server, client, message) - elif message.command_type == CommandTypeDC.LIST_PROCEDURES: - list_procedures(server, client, message) - elif message.command_type == CommandTypeDC.RUN_PROCEDURE: - run_procedure(server, client, message) - else: - logger.error(f"Unknown command type: {message.command_type}") + try: + message = deserialize_root_message(message_data) + if message.command_type == CommandTypeDC.UPDATE_SCENE: + update_scene(server, client, message) + elif message.command_type == CommandTypeDC.UPDATE_SERVER: + update_server(server, client, message) + elif message.command_type == CommandTypeDC.MESH_INFO_CALLBACK: + mesh_info_callback(server, client, message) + elif message.command_type == CommandTypeDC.LIST_PROCEDURES: + list_procedures(server, client, message) + elif message.command_type == CommandTypeDC.RUN_PROCEDURE: + run_procedure(server, client, message) + elif message.command_type == CommandTypeDC.LIST_FILE_OBJECTS: + list_file_objects(server, client, message) + else: + logger.error(f"Unknown command type: {message.command_type}") + on_error_reply(server, client, error_message=f"Unknown command type: {message.command_type}") + + except Exception as e: + logger.error(f"Error handling message: {e}") + on_error_reply(server, client, error_message=str(e)) diff --git a/src/ada/comms/msg_handling/list_file_objects.py b/src/ada/comms/msg_handling/list_file_objects.py new file mode 100644 index 000000000..d9f06d1e3 --- /dev/null +++ b/src/ada/comms/msg_handling/list_file_objects.py @@ -0,0 +1,31 @@ +from __future__ import annotations + +import asyncio +from typing import TYPE_CHECKING + +from ada.comms.fb_model_gen import CommandTypeDC, MessageDC, ServerDC, ServerReplyDC +from ada.comms.fb_serializer import serialize_message +from ada.config import logger + +if TYPE_CHECKING: + from ada.comms.wsock_server import ConnectedClient, WebSocketAsyncServer + + +def list_file_objects(server: WebSocketAsyncServer, client: ConnectedClient, message: MessageDC) -> None: + logger.info(f"Received message from {client} to list procedures") + logger.info(f"Message: {message}") + + file_objects = server.scene.file_objects + + reply_message = MessageDC( + instance_id=server.instance_id, + command_type=CommandTypeDC.SERVER_REPLY, + server=ServerDC(all_file_objects=file_objects), + target_id=client.instance_id, + target_group=client.group_type, + server_reply=ServerReplyDC(reply_to=message.command_type), + ) + fb_message = serialize_message(reply_message) + + # run the client.websocket in an event loop + asyncio.run(client.websocket.send(fb_message)) diff --git a/src/ada/comms/msg_handling/list_procedures.py b/src/ada/comms/msg_handling/list_procedures.py index 1ce15af6c..6b7e3d8e2 100644 --- a/src/ada/comms/msg_handling/list_procedures.py +++ b/src/ada/comms/msg_handling/list_procedures.py @@ -3,7 +3,7 @@ import asyncio from typing import TYPE_CHECKING -from ada.comms.fb_model_gen import CommandTypeDC, MessageDC, ServerReplyDC +from ada.comms.fb_model_gen import CommandTypeDC, MessageDC, ServerDC, ServerReplyDC from ada.comms.fb_serializer import serialize_message from ada.config import logger @@ -20,6 +20,7 @@ def list_procedures(server: WebSocketAsyncServer, client: ConnectedClient, messa reply_message = MessageDC( instance_id=server.instance_id, command_type=CommandTypeDC.SERVER_REPLY, + server=ServerDC(all_file_objects=server.scene.file_objects), procedure_store=procedure_store_dc, target_id=client.instance_id, target_group=client.group_type, diff --git a/src/ada/comms/msg_handling/mesh_info_callback.py b/src/ada/comms/msg_handling/mesh_info_callback.py index 96a1914b9..7876101fd 100644 --- a/src/ada/comms/msg_handling/mesh_info_callback.py +++ b/src/ada/comms/msg_handling/mesh_info_callback.py @@ -15,17 +15,17 @@ def mesh_info_callback(server: WebSocketAsyncServer, client: ConnectedClient, message: MessageDC) -> None: logger.info(f"Received message from {client} to update mesh info") logger.info(f"Message: {message}") - if server.scene_meta.ifc_sql_store is None: + if server.scene.ifc_sql_store is None: logger.error("IFC SQL store not initialized") return node_name = message.mesh_info.object_name num = node_name.replace("node", "") - meta = server.scene_meta.mesh_meta.get(f"id_sequence{num}") + meta = server.scene.mesh_meta.get(f"id_sequence{num}") guid = list(meta.keys()) if len(guid) == 1: guid = guid[0] - entity = server.scene_meta.ifc_sql_store.by_guid(guid) + entity = server.scene.ifc_sql_store.by_guid(guid) elif len(guid) > 1: raise ValueError(f"Multiple GUIDs found for node {node_name}") else: diff --git a/src/ada/comms/msg_handling/on_error_reply.py b/src/ada/comms/msg_handling/on_error_reply.py new file mode 100644 index 000000000..a1430cbf8 --- /dev/null +++ b/src/ada/comms/msg_handling/on_error_reply.py @@ -0,0 +1,23 @@ +from __future__ import annotations + +import asyncio +from typing import TYPE_CHECKING + +from ada.comms.fb_model_gen import CommandTypeDC, ErrorDC, MessageDC, ServerReplyDC +from ada.comms.fb_serializer import serialize_message + +if TYPE_CHECKING: + from ada.comms.wsock_server import ConnectedClient, WebSocketAsyncServer + + +def on_error_reply(server: WebSocketAsyncServer, client: ConnectedClient, error_message: str = None) -> None: + reply_message = MessageDC( + instance_id=server.instance_id, + command_type=CommandTypeDC.ERROR, + target_id=client.instance_id, + target_group=client.group_type, + server_reply=ServerReplyDC(error=ErrorDC(message=str(error_message))), + ) + fb_message = serialize_message(reply_message) + # run the client.websocket in an event loop + asyncio.run(client.websocket.send(fb_message)) diff --git a/src/ada/comms/msg_handling/update_scene.py b/src/ada/comms/msg_handling/update_scene.py index aaee11787..e32b20452 100644 --- a/src/ada/comms/msg_handling/update_scene.py +++ b/src/ada/comms/msg_handling/update_scene.py @@ -24,7 +24,7 @@ def update_scene(server: WebSocketAsyncServer, client: ConnectedClient, message: f.write(glb_file_data.filedata) tri_scene = trimesh.load(local_glb_file) - server.scene_meta.mesh_meta = tri_scene.metadata + server.scene.mesh_meta = tri_scene.metadata file_object = FileObjectDC( name=glb_file_data.name, @@ -33,4 +33,4 @@ def update_scene(server: WebSocketAsyncServer, client: ConnectedClient, message: file_type=glb_file_data.file_type, purpose=glb_file_data.purpose, ) - server.scene_meta.file_objects.append(file_object) + server.scene.file_objects.append(file_object) diff --git a/src/ada/comms/msg_handling/update_server.py b/src/ada/comms/msg_handling/update_server.py index faf27b54c..a0c3326f2 100644 --- a/src/ada/comms/msg_handling/update_server.py +++ b/src/ada/comms/msg_handling/update_server.py @@ -20,4 +20,5 @@ def update_server(server: WebSocketAsyncServer, client: ConnectedClient, message tmp_ifc_fp = pathlib.Path(add_file.filepath) tmp_sql_fp = tmp_ifc_fp.with_suffix(".sqlite") Ifc2SqlPatcher(tmp_ifc_fp, logger, dest_sql_file=tmp_sql_fp).patch() - server.scene_meta.ifc_sql_store = IfcSqlModel(tmp_sql_fp) + server.scene.ifc_sql_store = IfcSqlModel(tmp_sql_fp) + server.scene.file_objects.append(add_file) diff --git a/src/ada/comms/wsock/CameraParams.py b/src/ada/comms/wsock/CameraParams.py index 1c8932c5f..a92ff4618 100644 --- a/src/ada/comms/wsock/CameraParams.py +++ b/src/ada/comms/wsock/CameraParams.py @@ -4,10 +4,12 @@ import flatbuffers from flatbuffers.compat import import_numpy + np = import_numpy() + class CameraParams(object): - __slots__ = ['_tab'] + __slots__ = ["_tab"] @classmethod def GetRootAs(cls, buf, offset=0): @@ -20,6 +22,7 @@ def GetRootAs(cls, buf, offset=0): def GetRootAsCameraParams(cls, buf, offset=0): """This method is deprecated. Please switch to GetRootAs.""" return cls.GetRootAs(buf, offset) + # CameraParams def Init(self, buf, pos): self._tab = flatbuffers.table.Table(buf, pos) @@ -29,7 +32,9 @@ def Position(self, j): o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4)) if o != 0: a = self._tab.Vector(o) - return self._tab.Get(flatbuffers.number_types.Float32Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4)) + return self._tab.Get( + flatbuffers.number_types.Float32Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4) + ) return 0 # CameraParams @@ -56,7 +61,9 @@ def LookAt(self, j): o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6)) if o != 0: a = self._tab.Vector(o) - return self._tab.Get(flatbuffers.number_types.Float32Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4)) + return self._tab.Get( + flatbuffers.number_types.Float32Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4) + ) return 0 # CameraParams @@ -83,7 +90,9 @@ def Up(self, j): o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8)) if o != 0: a = self._tab.Vector(o) - return self._tab.Get(flatbuffers.number_types.Float32Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4)) + return self._tab.Get( + flatbuffers.number_types.Float32Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4) + ) return 0 # CameraParams @@ -133,74 +142,98 @@ def ForceCamera(self): return bool(self._tab.Get(flatbuffers.number_types.BoolFlags, o + self._tab.Pos)) return False + def CameraParamsStart(builder): builder.StartObject(7) + def Start(builder): CameraParamsStart(builder) + def CameraParamsAddPosition(builder, position): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(position), 0) + def AddPosition(builder, position): CameraParamsAddPosition(builder, position) + def CameraParamsStartPositionVector(builder, numElems): return builder.StartVector(4, numElems, 4) + def StartPositionVector(builder, numElems): return CameraParamsStartPositionVector(builder, numElems) + def CameraParamsAddLookAt(builder, lookAt): builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(lookAt), 0) + def AddLookAt(builder, lookAt): CameraParamsAddLookAt(builder, lookAt) + def CameraParamsStartLookAtVector(builder, numElems): return builder.StartVector(4, numElems, 4) + def StartLookAtVector(builder, numElems): return CameraParamsStartLookAtVector(builder, numElems) + def CameraParamsAddUp(builder, up): builder.PrependUOffsetTRelativeSlot(2, flatbuffers.number_types.UOffsetTFlags.py_type(up), 0) + def AddUp(builder, up): CameraParamsAddUp(builder, up) + def CameraParamsStartUpVector(builder, numElems): return builder.StartVector(4, numElems, 4) + def StartUpVector(builder, numElems): return CameraParamsStartUpVector(builder, numElems) + def CameraParamsAddFov(builder, fov): builder.PrependFloat32Slot(3, fov, 60.0) + def AddFov(builder, fov): CameraParamsAddFov(builder, fov) + def CameraParamsAddNear(builder, near): builder.PrependFloat32Slot(4, near, 0.1) + def AddNear(builder, near): CameraParamsAddNear(builder, near) + def CameraParamsAddFar(builder, far): builder.PrependFloat32Slot(5, far, 1000.0) + def AddFar(builder, far): CameraParamsAddFar(builder, far) + def CameraParamsAddForceCamera(builder, forceCamera): builder.PrependBoolSlot(6, forceCamera, 0) + def AddForceCamera(builder, forceCamera): CameraParamsAddForceCamera(builder, forceCamera) + def CameraParamsEnd(builder): return builder.EndObject() + def End(builder): return CameraParamsEnd(builder) diff --git a/src/ada/comms/wsock/CommandType.py b/src/ada/comms/wsock/CommandType.py index 744e101cb..bbca44c62 100644 --- a/src/ada/comms/wsock/CommandType.py +++ b/src/ada/comms/wsock/CommandType.py @@ -2,6 +2,7 @@ # namespace: wsock + class CommandType(object): PING = 0 PONG = 1 diff --git a/src/ada/comms/wsock/Error.py b/src/ada/comms/wsock/Error.py index aa776d014..7650463fc 100644 --- a/src/ada/comms/wsock/Error.py +++ b/src/ada/comms/wsock/Error.py @@ -4,10 +4,12 @@ import flatbuffers from flatbuffers.compat import import_numpy + np = import_numpy() + class Error(object): - __slots__ = ['_tab'] + __slots__ = ["_tab"] @classmethod def GetRootAs(cls, buf, offset=0): @@ -20,6 +22,7 @@ def GetRootAs(cls, buf, offset=0): def GetRootAsError(cls, buf, offset=0): """This method is deprecated. Please switch to GetRootAs.""" return cls.GetRootAs(buf, offset) + # Error def Init(self, buf, pos): self._tab = flatbuffers.table.Table(buf, pos) @@ -38,26 +41,34 @@ def Message(self): return self._tab.String(o + self._tab.Pos) return None + def ErrorStart(builder): builder.StartObject(2) + def Start(builder): ErrorStart(builder) + def ErrorAddCode(builder, code): builder.PrependInt32Slot(0, code, 0) + def AddCode(builder, code): ErrorAddCode(builder, code) + def ErrorAddMessage(builder, message): builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(message), 0) + def AddMessage(builder, message): ErrorAddMessage(builder, message) + def ErrorEnd(builder): return builder.EndObject() + def End(builder): return ErrorEnd(builder) diff --git a/src/ada/comms/wsock/FileObject.py b/src/ada/comms/wsock/FileObject.py index b28bd12f2..fb54bfcb9 100644 --- a/src/ada/comms/wsock/FileObject.py +++ b/src/ada/comms/wsock/FileObject.py @@ -4,10 +4,12 @@ import flatbuffers from flatbuffers.compat import import_numpy + np = import_numpy() + class FileObject(object): - __slots__ = ['_tab'] + __slots__ = ["_tab"] @classmethod def GetRootAs(cls, buf, offset=0): @@ -20,6 +22,7 @@ def GetRootAs(cls, buf, offset=0): def GetRootAsFileObject(cls, buf, offset=0): """This method is deprecated. Please switch to GetRootAs.""" return cls.GetRootAs(buf, offset) + # FileObject def Init(self, buf, pos): self._tab = flatbuffers.table.Table(buf, pos) @@ -57,7 +60,9 @@ def Filedata(self, j): o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12)) if o != 0: a = self._tab.Vector(o) - return self._tab.Get(flatbuffers.number_types.Uint8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1)) + return self._tab.Get( + flatbuffers.number_types.Uint8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1) + ) return 0 # FileObject @@ -79,50 +84,66 @@ def FiledataIsNone(self): o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12)) return o == 0 + def FileObjectStart(builder): builder.StartObject(5) + def Start(builder): FileObjectStart(builder) + def FileObjectAddName(builder, name): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(name), 0) + def AddName(builder, name): FileObjectAddName(builder, name) + def FileObjectAddFileType(builder, fileType): builder.PrependInt8Slot(1, fileType, 0) + def AddFileType(builder, fileType): FileObjectAddFileType(builder, fileType) + def FileObjectAddPurpose(builder, purpose): builder.PrependInt8Slot(2, purpose, 0) + def AddPurpose(builder, purpose): FileObjectAddPurpose(builder, purpose) + def FileObjectAddFilepath(builder, filepath): builder.PrependUOffsetTRelativeSlot(3, flatbuffers.number_types.UOffsetTFlags.py_type(filepath), 0) + def AddFilepath(builder, filepath): FileObjectAddFilepath(builder, filepath) + def FileObjectAddFiledata(builder, filedata): builder.PrependUOffsetTRelativeSlot(4, flatbuffers.number_types.UOffsetTFlags.py_type(filedata), 0) + def AddFiledata(builder, filedata): FileObjectAddFiledata(builder, filedata) + def FileObjectStartFiledataVector(builder, numElems): return builder.StartVector(1, numElems, 1) + def StartFiledataVector(builder, numElems): return FileObjectStartFiledataVector(builder, numElems) + def FileObjectEnd(builder): return builder.EndObject() + def End(builder): return FileObjectEnd(builder) diff --git a/src/ada/comms/wsock/FilePurpose.py b/src/ada/comms/wsock/FilePurpose.py index 531dfe944..2f236426c 100644 --- a/src/ada/comms/wsock/FilePurpose.py +++ b/src/ada/comms/wsock/FilePurpose.py @@ -2,6 +2,7 @@ # namespace: wsock + class FilePurpose(object): DESIGN = 0 ANALYSIS = 1 diff --git a/src/ada/comms/wsock/FileType.py b/src/ada/comms/wsock/FileType.py index c2ae703fd..3e09c82be 100644 --- a/src/ada/comms/wsock/FileType.py +++ b/src/ada/comms/wsock/FileType.py @@ -2,6 +2,7 @@ # namespace: wsock + class FileType(object): IFC = 0 GLB = 1 diff --git a/src/ada/comms/wsock/MeshInfo.py b/src/ada/comms/wsock/MeshInfo.py index b8e8151a1..b15051ba0 100644 --- a/src/ada/comms/wsock/MeshInfo.py +++ b/src/ada/comms/wsock/MeshInfo.py @@ -4,10 +4,12 @@ import flatbuffers from flatbuffers.compat import import_numpy + np = import_numpy() + class MeshInfo(object): - __slots__ = ['_tab'] + __slots__ = ["_tab"] @classmethod def GetRootAs(cls, buf, offset=0): @@ -20,6 +22,7 @@ def GetRootAs(cls, buf, offset=0): def GetRootAsMeshInfo(cls, buf, offset=0): """This method is deprecated. Please switch to GetRootAs.""" return cls.GetRootAs(buf, offset) + # MeshInfo def Init(self, buf, pos): self._tab = flatbuffers.table.Table(buf, pos) @@ -45,32 +48,42 @@ def JsonData(self): return self._tab.String(o + self._tab.Pos) return None + def MeshInfoStart(builder): builder.StartObject(3) + def Start(builder): MeshInfoStart(builder) + def MeshInfoAddObjectName(builder, objectName): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(objectName), 0) + def AddObjectName(builder, objectName): MeshInfoAddObjectName(builder, objectName) + def MeshInfoAddFaceIndex(builder, faceIndex): builder.PrependInt32Slot(1, faceIndex, 0) + def AddFaceIndex(builder, faceIndex): MeshInfoAddFaceIndex(builder, faceIndex) + def MeshInfoAddJsonData(builder, jsonData): builder.PrependUOffsetTRelativeSlot(2, flatbuffers.number_types.UOffsetTFlags.py_type(jsonData), 0) + def AddJsonData(builder, jsonData): MeshInfoAddJsonData(builder, jsonData) + def MeshInfoEnd(builder): return builder.EndObject() + def End(builder): return MeshInfoEnd(builder) diff --git a/src/ada/comms/wsock/Message.py b/src/ada/comms/wsock/Message.py index 8833650cf..7cd2fa6b1 100644 --- a/src/ada/comms/wsock/Message.py +++ b/src/ada/comms/wsock/Message.py @@ -4,10 +4,12 @@ import flatbuffers from flatbuffers.compat import import_numpy + np = import_numpy() + class Message(object): - __slots__ = ['_tab'] + __slots__ = ["_tab"] @classmethod def GetRootAs(cls, buf, offset=0): @@ -20,6 +22,7 @@ def GetRootAs(cls, buf, offset=0): def GetRootAsMessage(cls, buf, offset=0): """This method is deprecated. Please switch to GetRootAs.""" return cls.GetRootAs(buf, offset) + # Message def Init(self, buf, pos): self._tab = flatbuffers.table.Table(buf, pos) @@ -44,6 +47,7 @@ def Scene(self): if o != 0: x = self._tab.Indirect(o + self._tab.Pos) from ada.comms.wsock.Scene import Scene + obj = Scene() obj.Init(self._tab.Bytes, x) return obj @@ -55,6 +59,7 @@ def Server(self): if o != 0: x = self._tab.Indirect(o + self._tab.Pos) from ada.comms.wsock.Server import Server + obj = Server() obj.Init(self._tab.Bytes, x) return obj @@ -66,6 +71,7 @@ def MeshInfo(self): if o != 0: x = self._tab.Indirect(o + self._tab.Pos) from ada.comms.wsock.MeshInfo import MeshInfo + obj = MeshInfo() obj.Init(self._tab.Bytes, x) return obj @@ -100,6 +106,7 @@ def WebClients(self, j): x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4 x = self._tab.Indirect(x) from ada.comms.wsock.WebClient import WebClient + obj = WebClient() obj.Init(self._tab.Bytes, x) return obj @@ -123,6 +130,7 @@ def ProcedureStore(self): if o != 0: x = self._tab.Indirect(o + self._tab.Pos) from ada.comms.wsock.ProcedureStore import ProcedureStore + obj = ProcedureStore() obj.Init(self._tab.Bytes, x) return obj @@ -134,91 +142,120 @@ def ServerReply(self): if o != 0: x = self._tab.Indirect(o + self._tab.Pos) from ada.comms.wsock.ServerReply import ServerReply + obj = ServerReply() obj.Init(self._tab.Bytes, x) return obj return None + def MessageStart(builder): builder.StartObject(11) + def Start(builder): MessageStart(builder) + def MessageAddInstanceId(builder, instanceId): builder.PrependInt32Slot(0, instanceId, 0) + def AddInstanceId(builder, instanceId): MessageAddInstanceId(builder, instanceId) + def MessageAddCommandType(builder, commandType): builder.PrependInt8Slot(1, commandType, 0) + def AddCommandType(builder, commandType): MessageAddCommandType(builder, commandType) + def MessageAddScene(builder, scene): builder.PrependUOffsetTRelativeSlot(2, flatbuffers.number_types.UOffsetTFlags.py_type(scene), 0) + def AddScene(builder, scene): MessageAddScene(builder, scene) + def MessageAddServer(builder, server): builder.PrependUOffsetTRelativeSlot(3, flatbuffers.number_types.UOffsetTFlags.py_type(server), 0) + def AddServer(builder, server): MessageAddServer(builder, server) + def MessageAddMeshInfo(builder, meshInfo): builder.PrependUOffsetTRelativeSlot(4, flatbuffers.number_types.UOffsetTFlags.py_type(meshInfo), 0) + def AddMeshInfo(builder, meshInfo): MessageAddMeshInfo(builder, meshInfo) + def MessageAddTargetGroup(builder, targetGroup): builder.PrependInt8Slot(5, targetGroup, 0) + def AddTargetGroup(builder, targetGroup): MessageAddTargetGroup(builder, targetGroup) + def MessageAddClientType(builder, clientType): builder.PrependInt8Slot(6, clientType, 0) + def AddClientType(builder, clientType): MessageAddClientType(builder, clientType) + def MessageAddTargetId(builder, targetId): builder.PrependInt32Slot(7, targetId, 0) + def AddTargetId(builder, targetId): MessageAddTargetId(builder, targetId) + def MessageAddWebClients(builder, webClients): builder.PrependUOffsetTRelativeSlot(8, flatbuffers.number_types.UOffsetTFlags.py_type(webClients), 0) + def AddWebClients(builder, webClients): MessageAddWebClients(builder, webClients) + def MessageStartWebClientsVector(builder, numElems): return builder.StartVector(4, numElems, 4) + def StartWebClientsVector(builder, numElems): return MessageStartWebClientsVector(builder, numElems) + def MessageAddProcedureStore(builder, procedureStore): builder.PrependUOffsetTRelativeSlot(9, flatbuffers.number_types.UOffsetTFlags.py_type(procedureStore), 0) + def AddProcedureStore(builder, procedureStore): MessageAddProcedureStore(builder, procedureStore) + def MessageAddServerReply(builder, serverReply): builder.PrependUOffsetTRelativeSlot(10, flatbuffers.number_types.UOffsetTFlags.py_type(serverReply), 0) + def AddServerReply(builder, serverReply): MessageAddServerReply(builder, serverReply) + def MessageEnd(builder): return builder.EndObject() + def End(builder): return MessageEnd(builder) diff --git a/src/ada/comms/wsock/Parameter.py b/src/ada/comms/wsock/Parameter.py index 8a10042ac..579a1fd67 100644 --- a/src/ada/comms/wsock/Parameter.py +++ b/src/ada/comms/wsock/Parameter.py @@ -4,10 +4,12 @@ import flatbuffers from flatbuffers.compat import import_numpy + np = import_numpy() + class Parameter(object): - __slots__ = ['_tab'] + __slots__ = ["_tab"] @classmethod def GetRootAs(cls, buf, offset=0): @@ -20,6 +22,7 @@ def GetRootAs(cls, buf, offset=0): def GetRootAsParameter(cls, buf, offset=0): """This method is deprecated. Please switch to GetRootAs.""" return cls.GetRootAs(buf, offset) + # Parameter def Init(self, buf, pos): self._tab = flatbuffers.table.Table(buf, pos) @@ -45,32 +48,42 @@ def Value(self): return self._tab.String(o + self._tab.Pos) return None + def ParameterStart(builder): builder.StartObject(3) + def Start(builder): ParameterStart(builder) + def ParameterAddName(builder, name): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(name), 0) + def AddName(builder, name): ParameterAddName(builder, name) + def ParameterAddType(builder, type): builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(type), 0) + def AddType(builder, type): ParameterAddType(builder, type) + def ParameterAddValue(builder, value): builder.PrependUOffsetTRelativeSlot(2, flatbuffers.number_types.UOffsetTFlags.py_type(value), 0) + def AddValue(builder, value): ParameterAddValue(builder, value) + def ParameterEnd(builder): return builder.EndObject() + def End(builder): return ParameterEnd(builder) diff --git a/src/ada/comms/wsock/Procedure.py b/src/ada/comms/wsock/Procedure.py index 296b463ac..c2d8058b3 100644 --- a/src/ada/comms/wsock/Procedure.py +++ b/src/ada/comms/wsock/Procedure.py @@ -4,10 +4,12 @@ import flatbuffers from flatbuffers.compat import import_numpy + np = import_numpy() + class Procedure(object): - __slots__ = ['_tab'] + __slots__ = ["_tab"] @classmethod def GetRootAs(cls, buf, offset=0): @@ -20,6 +22,7 @@ def GetRootAs(cls, buf, offset=0): def GetRootAsProcedure(cls, buf, offset=0): """This method is deprecated. Please switch to GetRootAs.""" return cls.GetRootAs(buf, offset) + # Procedure def Init(self, buf, pos): self._tab = flatbuffers.table.Table(buf, pos) @@ -53,6 +56,7 @@ def Parameters(self, j): x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4 x = self._tab.Indirect(x) from ada.comms.wsock.Parameter import Parameter + obj = Parameter() obj.Init(self._tab.Bytes, x) return obj @@ -98,68 +102,90 @@ def State(self): return self._tab.Get(flatbuffers.number_types.Int8Flags, o + self._tab.Pos) return 0 + def ProcedureStart(builder): builder.StartObject(8) + def Start(builder): ProcedureStart(builder) + def ProcedureAddName(builder, name): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(name), 0) + def AddName(builder, name): ProcedureAddName(builder, name) + def ProcedureAddDescription(builder, description): builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(description), 0) + def AddDescription(builder, description): ProcedureAddDescription(builder, description) + def ProcedureAddScriptFileLocation(builder, scriptFileLocation): builder.PrependUOffsetTRelativeSlot(2, flatbuffers.number_types.UOffsetTFlags.py_type(scriptFileLocation), 0) + def AddScriptFileLocation(builder, scriptFileLocation): ProcedureAddScriptFileLocation(builder, scriptFileLocation) + def ProcedureAddParameters(builder, parameters): builder.PrependUOffsetTRelativeSlot(3, flatbuffers.number_types.UOffsetTFlags.py_type(parameters), 0) + def AddParameters(builder, parameters): ProcedureAddParameters(builder, parameters) + def ProcedureStartParametersVector(builder, numElems): return builder.StartVector(4, numElems, 4) + def StartParametersVector(builder, numElems): return ProcedureStartParametersVector(builder, numElems) + def ProcedureAddInputFileVar(builder, inputFileVar): builder.PrependUOffsetTRelativeSlot(4, flatbuffers.number_types.UOffsetTFlags.py_type(inputFileVar), 0) + def AddInputFileVar(builder, inputFileVar): ProcedureAddInputFileVar(builder, inputFileVar) + def ProcedureAddInputFileType(builder, inputFileType): builder.PrependInt8Slot(5, inputFileType, 0) + def AddInputFileType(builder, inputFileType): ProcedureAddInputFileType(builder, inputFileType) + def ProcedureAddExportFileType(builder, exportFileType): builder.PrependInt8Slot(6, exportFileType, 0) + def AddExportFileType(builder, exportFileType): ProcedureAddExportFileType(builder, exportFileType) + def ProcedureAddState(builder, state): builder.PrependInt8Slot(7, state, 0) + def AddState(builder, state): ProcedureAddState(builder, state) + def ProcedureEnd(builder): return builder.EndObject() + def End(builder): return ProcedureEnd(builder) diff --git a/src/ada/comms/wsock/ProcedureStart.py b/src/ada/comms/wsock/ProcedureStart.py index ca364cc83..97e242052 100644 --- a/src/ada/comms/wsock/ProcedureStart.py +++ b/src/ada/comms/wsock/ProcedureStart.py @@ -4,10 +4,12 @@ import flatbuffers from flatbuffers.compat import import_numpy + np = import_numpy() + class ProcedureStart(object): - __slots__ = ['_tab'] + __slots__ = ["_tab"] @classmethod def GetRootAs(cls, buf, offset=0): @@ -20,6 +22,7 @@ def GetRootAs(cls, buf, offset=0): def GetRootAsProcedureStart(cls, buf, offset=0): """This method is deprecated. Please switch to GetRootAs.""" return cls.GetRootAs(buf, offset) + # ProcedureStart def Init(self, buf, pos): self._tab = flatbuffers.table.Table(buf, pos) @@ -39,6 +42,7 @@ def Parameters(self, j): x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4 x = self._tab.Indirect(x) from ada.comms.wsock.Parameter import Parameter + obj = Parameter() obj.Init(self._tab.Bytes, x) return obj @@ -56,32 +60,42 @@ def ParametersIsNone(self): o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6)) return o == 0 + def ProcedureStartStart(builder): builder.StartObject(2) + def Start(builder): ProcedureStartStart(builder) + def ProcedureStartAddProcedureName(builder, procedureName): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(procedureName), 0) + def AddProcedureName(builder, procedureName): ProcedureStartAddProcedureName(builder, procedureName) + def ProcedureStartAddParameters(builder, parameters): builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(parameters), 0) + def AddParameters(builder, parameters): ProcedureStartAddParameters(builder, parameters) + def ProcedureStartStartParametersVector(builder, numElems): return builder.StartVector(4, numElems, 4) + def StartParametersVector(builder, numElems): return ProcedureStartStartParametersVector(builder, numElems) + def ProcedureStartEnd(builder): return builder.EndObject() + def End(builder): return ProcedureStartEnd(builder) diff --git a/src/ada/comms/wsock/ProcedureState.py b/src/ada/comms/wsock/ProcedureState.py index 10037640b..3131ef025 100644 --- a/src/ada/comms/wsock/ProcedureState.py +++ b/src/ada/comms/wsock/ProcedureState.py @@ -2,6 +2,7 @@ # namespace: wsock + class ProcedureState(object): IDLE = 0 RUNNING = 1 diff --git a/src/ada/comms/wsock/ProcedureStore.py b/src/ada/comms/wsock/ProcedureStore.py index bacd424e3..b06f189b1 100644 --- a/src/ada/comms/wsock/ProcedureStore.py +++ b/src/ada/comms/wsock/ProcedureStore.py @@ -4,10 +4,12 @@ import flatbuffers from flatbuffers.compat import import_numpy + np = import_numpy() + class ProcedureStore(object): - __slots__ = ['_tab'] + __slots__ = ["_tab"] @classmethod def GetRootAs(cls, buf, offset=0): @@ -20,6 +22,7 @@ def GetRootAs(cls, buf, offset=0): def GetRootAsProcedureStore(cls, buf, offset=0): """This method is deprecated. Please switch to GetRootAs.""" return cls.GetRootAs(buf, offset) + # ProcedureStore def Init(self, buf, pos): self._tab = flatbuffers.table.Table(buf, pos) @@ -32,6 +35,7 @@ def Procedures(self, j): x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4 x = self._tab.Indirect(x) from ada.comms.wsock.Procedure import Procedure + obj = Procedure() obj.Init(self._tab.Bytes, x) return obj @@ -55,37 +59,48 @@ def StartProcedure(self): if o != 0: x = self._tab.Indirect(o + self._tab.Pos) from ada.comms.wsock.ProcedureStart import ProcedureStart + obj = ProcedureStart() obj.Init(self._tab.Bytes, x) return obj return None + def ProcedureStoreStart(builder): builder.StartObject(2) + def Start(builder): ProcedureStoreStart(builder) + def ProcedureStoreAddProcedures(builder, procedures): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(procedures), 0) + def AddProcedures(builder, procedures): ProcedureStoreAddProcedures(builder, procedures) + def ProcedureStoreStartProceduresVector(builder, numElems): return builder.StartVector(4, numElems, 4) + def StartProceduresVector(builder, numElems): return ProcedureStoreStartProceduresVector(builder, numElems) + def ProcedureStoreAddStartProcedure(builder, startProcedure): builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(startProcedure), 0) + def AddStartProcedure(builder, startProcedure): ProcedureStoreAddStartProcedure(builder, startProcedure) + def ProcedureStoreEnd(builder): return builder.EndObject() + def End(builder): return ProcedureStoreEnd(builder) diff --git a/src/ada/comms/wsock/Scene.py b/src/ada/comms/wsock/Scene.py index f3fe66ac4..13d08e727 100644 --- a/src/ada/comms/wsock/Scene.py +++ b/src/ada/comms/wsock/Scene.py @@ -4,10 +4,12 @@ import flatbuffers from flatbuffers.compat import import_numpy + np = import_numpy() + class Scene(object): - __slots__ = ['_tab'] + __slots__ = ["_tab"] @classmethod def GetRootAs(cls, buf, offset=0): @@ -20,6 +22,7 @@ def GetRootAs(cls, buf, offset=0): def GetRootAsScene(cls, buf, offset=0): """This method is deprecated. Please switch to GetRootAs.""" return cls.GetRootAs(buf, offset) + # Scene def Init(self, buf, pos): self._tab = flatbuffers.table.Table(buf, pos) @@ -37,6 +40,7 @@ def CameraParams(self): if o != 0: x = self._tab.Indirect(o + self._tab.Pos) from ada.comms.wsock.CameraParams import CameraParams + obj = CameraParams() obj.Init(self._tab.Bytes, x) return obj @@ -48,37 +52,48 @@ def CurrentFile(self): if o != 0: x = self._tab.Indirect(o + self._tab.Pos) from ada.comms.wsock.FileObject import FileObject + obj = FileObject() obj.Init(self._tab.Bytes, x) return obj return None + def SceneStart(builder): builder.StartObject(3) + def Start(builder): SceneStart(builder) + def SceneAddOperation(builder, operation): builder.PrependInt8Slot(0, operation, 0) + def AddOperation(builder, operation): SceneAddOperation(builder, operation) + def SceneAddCameraParams(builder, cameraParams): builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(cameraParams), 0) + def AddCameraParams(builder, cameraParams): SceneAddCameraParams(builder, cameraParams) + def SceneAddCurrentFile(builder, currentFile): builder.PrependUOffsetTRelativeSlot(2, flatbuffers.number_types.UOffsetTFlags.py_type(currentFile), 0) + def AddCurrentFile(builder, currentFile): SceneAddCurrentFile(builder, currentFile) + def SceneEnd(builder): return builder.EndObject() + def End(builder): return SceneEnd(builder) diff --git a/src/ada/comms/wsock/SceneOperations.py b/src/ada/comms/wsock/SceneOperations.py index 91369f0d3..b07fc9321 100644 --- a/src/ada/comms/wsock/SceneOperations.py +++ b/src/ada/comms/wsock/SceneOperations.py @@ -2,6 +2,7 @@ # namespace: wsock + class SceneOperations(object): ADD = 0 REMOVE = 1 diff --git a/src/ada/comms/wsock/Server.py b/src/ada/comms/wsock/Server.py index 1d3dd6064..376837cd9 100644 --- a/src/ada/comms/wsock/Server.py +++ b/src/ada/comms/wsock/Server.py @@ -4,10 +4,12 @@ import flatbuffers from flatbuffers.compat import import_numpy + np = import_numpy() + class Server(object): - __slots__ = ['_tab'] + __slots__ = ["_tab"] @classmethod def GetRootAs(cls, buf, offset=0): @@ -20,6 +22,7 @@ def GetRootAs(cls, buf, offset=0): def GetRootAsServer(cls, buf, offset=0): """This method is deprecated. Please switch to GetRootAs.""" return cls.GetRootAs(buf, offset) + # Server def Init(self, buf, pos): self._tab = flatbuffers.table.Table(buf, pos) @@ -30,6 +33,7 @@ def AddFileObject(self): if o != 0: x = self._tab.Indirect(o + self._tab.Pos) from ada.comms.wsock.FileObject import FileObject + obj = FileObject() obj.Init(self._tab.Bytes, x) return obj @@ -43,6 +47,7 @@ def AllFileObjects(self, j): x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4 x = self._tab.Indirect(x) from ada.comms.wsock.FileObject import FileObject + obj = FileObject() obj.Init(self._tab.Bytes, x) return obj @@ -60,32 +65,42 @@ def AllFileObjectsIsNone(self): o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6)) return o == 0 + def ServerStart(builder): builder.StartObject(2) + def Start(builder): ServerStart(builder) + def ServerAddAddFileObject(builder, addFileObject): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(addFileObject), 0) + def AddAddFileObject(builder, addFileObject): ServerAddAddFileObject(builder, addFileObject) + def ServerAddAllFileObjects(builder, allFileObjects): builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(allFileObjects), 0) + def AddAllFileObjects(builder, allFileObjects): ServerAddAllFileObjects(builder, allFileObjects) + def ServerStartAllFileObjectsVector(builder, numElems): return builder.StartVector(4, numElems, 4) + def StartAllFileObjectsVector(builder, numElems): return ServerStartAllFileObjectsVector(builder, numElems) + def ServerEnd(builder): return builder.EndObject() + def End(builder): return ServerEnd(builder) diff --git a/src/ada/comms/wsock/ServerReply.py b/src/ada/comms/wsock/ServerReply.py index 4d7337d61..d16934b65 100644 --- a/src/ada/comms/wsock/ServerReply.py +++ b/src/ada/comms/wsock/ServerReply.py @@ -4,10 +4,12 @@ import flatbuffers from flatbuffers.compat import import_numpy + np = import_numpy() + class ServerReply(object): - __slots__ = ['_tab'] + __slots__ = ["_tab"] @classmethod def GetRootAs(cls, buf, offset=0): @@ -20,6 +22,7 @@ def GetRootAs(cls, buf, offset=0): def GetRootAsServerReply(cls, buf, offset=0): """This method is deprecated. Please switch to GetRootAs.""" return cls.GetRootAs(buf, offset) + # ServerReply def Init(self, buf, pos): self._tab = flatbuffers.table.Table(buf, pos) @@ -44,37 +47,48 @@ def Error(self): if o != 0: x = self._tab.Indirect(o + self._tab.Pos) from ada.comms.wsock.Error import Error + obj = Error() obj.Init(self._tab.Bytes, x) return obj return None + def ServerReplyStart(builder): builder.StartObject(3) + def Start(builder): ServerReplyStart(builder) + def ServerReplyAddMessage(builder, message): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(message), 0) + def AddMessage(builder, message): ServerReplyAddMessage(builder, message) + def ServerReplyAddReplyTo(builder, replyTo): builder.PrependInt8Slot(1, replyTo, 0) + def AddReplyTo(builder, replyTo): ServerReplyAddReplyTo(builder, replyTo) + def ServerReplyAddError(builder, error): builder.PrependUOffsetTRelativeSlot(2, flatbuffers.number_types.UOffsetTFlags.py_type(error), 0) + def AddError(builder, error): ServerReplyAddError(builder, error) + def ServerReplyEnd(builder): return builder.EndObject() + def End(builder): return ServerReplyEnd(builder) diff --git a/src/ada/comms/wsock/TargetType.py b/src/ada/comms/wsock/TargetType.py index 2141d9e79..73e6ac6bc 100644 --- a/src/ada/comms/wsock/TargetType.py +++ b/src/ada/comms/wsock/TargetType.py @@ -2,6 +2,7 @@ # namespace: wsock + class TargetType(object): WEB = 0 LOCAL = 1 diff --git a/src/ada/comms/wsock/WebClient.py b/src/ada/comms/wsock/WebClient.py index a3ccffd45..517a9e889 100644 --- a/src/ada/comms/wsock/WebClient.py +++ b/src/ada/comms/wsock/WebClient.py @@ -4,10 +4,12 @@ import flatbuffers from flatbuffers.compat import import_numpy + np = import_numpy() + class WebClient(object): - __slots__ = ['_tab'] + __slots__ = ["_tab"] @classmethod def GetRootAs(cls, buf, offset=0): @@ -20,6 +22,7 @@ def GetRootAs(cls, buf, offset=0): def GetRootAsWebClient(cls, buf, offset=0): """This method is deprecated. Please switch to GetRootAs.""" return cls.GetRootAs(buf, offset) + # WebClient def Init(self, buf, pos): self._tab = flatbuffers.table.Table(buf, pos) @@ -52,38 +55,50 @@ def Port(self): return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos) return 0 + def WebClientStart(builder): builder.StartObject(4) + def Start(builder): WebClientStart(builder) + def WebClientAddInstanceId(builder, instanceId): builder.PrependInt32Slot(0, instanceId, 0) + def AddInstanceId(builder, instanceId): WebClientAddInstanceId(builder, instanceId) + def WebClientAddName(builder, name): builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(name), 0) + def AddName(builder, name): WebClientAddName(builder, name) + def WebClientAddAddress(builder, address): builder.PrependUOffsetTRelativeSlot(2, flatbuffers.number_types.UOffsetTFlags.py_type(address), 0) + def AddAddress(builder, address): WebClientAddAddress(builder, address) + def WebClientAddPort(builder, port): builder.PrependInt32Slot(3, port, 0) + def AddPort(builder, port): WebClientAddPort(builder, port) + def WebClientEnd(builder): return builder.EndObject() + def End(builder): return WebClientEnd(builder) diff --git a/src/ada/comms/wsock_client_async.py b/src/ada/comms/wsock_client_async.py index 2038a55ef..1dd3bccc5 100644 --- a/src/ada/comms/wsock_client_async.py +++ b/src/ada/comms/wsock_client_async.py @@ -5,6 +5,7 @@ import trimesh import websockets +from ada.comms.exceptions import ServerError from ada.comms.fb_deserializer import deserialize_root_message from ada.comms.fb_model_gen import ( CommandTypeDC, @@ -83,7 +84,12 @@ async def receive(self, timeout=None) -> MessageDC: message = await asyncio.wait_for(self.websocket.recv(), timeout) else: message = await self.websocket.recv() - return deserialize_root_message(message) + msg = deserialize_root_message(message) + + if msg.server_reply.error is not None: + raise ServerError(msg.server_reply.error.message) + + return msg async def list_procedures(self) -> list[ProcedureDC]: await self.websocket.send(self._list_procedures_prep()) @@ -93,7 +99,7 @@ async def list_procedures(self) -> list[ProcedureDC]: async def list_server_file_objects(self) -> list[FileObjectDC]: await self.websocket.send(self._list_server_file_objects_prep()) msg = await self.receive() - return msg.server.add_file_object + return msg.server.all_file_objects async def run_procedure(self, procedure: ProcedureStartDC) -> None: """Runs a procedure with the given name and arguments.""" diff --git a/src/ada/comms/wsock_client_base.py b/src/ada/comms/wsock_client_base.py index 18d757000..806886f98 100644 --- a/src/ada/comms/wsock_client_base.py +++ b/src/ada/comms/wsock_client_base.py @@ -17,7 +17,8 @@ ProcedureStoreDC, SceneDC, SceneOperationsDC, - TargetTypeDC, ServerDC, + ServerDC, + TargetTypeDC, ) from ada.comms.fb_serializer import serialize_message from ada.comms.wsockets_utils import client_as_str @@ -107,6 +108,14 @@ def _run_procedure_prep(self, procedure: ProcedureStartDC) -> bytes: ) return serialize_message(message) + def _list_server_file_objects_prep(self) -> bytes: + message = MessageDC( + instance_id=self.instance_id, + command_type=CommandTypeDC.LIST_FILE_OBJECTS, + target_group=TargetTypeDC.SERVER, + ) + return serialize_message(message) + @abstractmethod def connect(self): pass diff --git a/src/ada/comms/wsock_client_sync.py b/src/ada/comms/wsock_client_sync.py index 801b4788b..8e72a30eb 100644 --- a/src/ada/comms/wsock_client_sync.py +++ b/src/ada/comms/wsock_client_sync.py @@ -83,6 +83,11 @@ def list_procedures(self) -> list[ProcedureDC]: msg = self.receive() return msg.procedure_store.procedures + def list_server_file_objects(self) -> list[FileObjectDC]: + self.websocket.send(self._list_server_file_objects_prep()) + msg = self.receive() + return msg.server.all_file_objects + def run_procedure(self, procedure: ProcedureStartDC) -> None: """Runs a procedure with the given name and arguments.""" self.websocket.send(self._run_procedure_prep(procedure)) diff --git a/src/ada/comms/wsock_server.py b/src/ada/comms/wsock_server.py index e335adf15..8260c1050 100644 --- a/src/ada/comms/wsock_server.py +++ b/src/ada/comms/wsock_server.py @@ -54,7 +54,7 @@ async def process_client(websocket, path) -> ConnectedClient: @dataclass -class SceneMeta: +class Scene: file_objects: list[FileObjectDC] = field(default_factory=list) ifc_sql_store: IfcSqlModel = None mesh_meta: dict = None @@ -94,7 +94,7 @@ def __init__( self.on_disconnect = on_disconnect self.on_message = on_message self.on_unsent_message = on_unsent_message - self.scene_meta = SceneMeta() + self.scene = Scene() self.instance_id = random.randint(0, 2**31 - 1) # Generates a random int32 value self.msg_queue = asyncio.Queue() self.procedure_store = ProcedureStore() diff --git a/src/frontend/src/components/node_editor/NodeEditorComponent.tsx b/src/frontend/src/components/node_editor/NodeEditorComponent.tsx index 1d43c7f92..03b2b3487 100644 --- a/src/frontend/src/components/node_editor/NodeEditorComponent.tsx +++ b/src/frontend/src/components/node_editor/NodeEditorComponent.tsx @@ -2,9 +2,10 @@ import React from 'react'; import {Rnd} from 'react-rnd'; import {Background, Controls, MiniMap, ReactFlow,} from '@xyflow/react'; import '@xyflow/react/dist/style.css'; -import {request_list_of_procedures} from "../../utils/node_editor/request_list_of_procedures"; +import {request_list_of_nodes} from "../../utils/node_editor/request_list_of_nodes"; import {useNodeEditorStore} from '../../state/useNodeEditorStore'; // Import the Zustand store -import InfoPanel from './InfoPanel'; // Import the InfoPanel component +import InfoPanel from './InfoPanel'; +import {run_sequence} from "../../utils/node_editor/run_sequence"; // Import the InfoPanel component const info_svg = @@ -42,18 +43,26 @@ const NodeEditorComponent: React.FC = () => {
Node Editor
- {/*{info_svg}*/} + + {/* Content Area */}
onNodesChange(changes)} diff --git a/src/frontend/src/utils/fb_handling/handle_incoming_buffers.ts b/src/frontend/src/utils/fb_handling/handle_incoming_buffers.ts index 18cdba589..a040cb907 100644 --- a/src/frontend/src/utils/fb_handling/handle_incoming_buffers.ts +++ b/src/frontend/src/utils/fb_handling/handle_incoming_buffers.ts @@ -3,7 +3,7 @@ import * as flatbuffers from "flatbuffers"; import {reply_ping} from "./reply_ping"; import {update_scene} from "../scene/update_scene"; import {receive_mesh_info_reply} from "../mesh_select/receive_mesh_info_reply"; -import {update_list_of_procedures} from "../node_editor/update_list_of_procedures"; +import {update_nodes} from "../node_editor/update_nodes"; export const handleFlatbufferMessage = (buffer: ArrayBuffer) => { // Wrap ArrayBuffer into FlatBuffer ByteBuffer @@ -15,12 +15,12 @@ export const handleFlatbufferMessage = (buffer: ArrayBuffer) => { reply_ping(message); } else if (command_type === CommandType.UPDATE_SCENE) { update_scene(message); - update_list_of_procedures(message); + update_nodes(message); } else if (command_type === CommandType.MESH_INFO_REPLY) { receive_mesh_info_reply(message); } else if (command_type == CommandType.SERVER_REPLY) { if (message.serverReply()?.replyTo() === CommandType.LIST_PROCEDURES) { - update_list_of_procedures(message); + update_nodes(message); } else if (message.serverReply()?.replyTo() === CommandType.MESH_INFO_CALLBACK) { receive_mesh_info_reply(message); } diff --git a/src/frontend/src/utils/node_editor/request_list_of_procedures.ts b/src/frontend/src/utils/node_editor/request_list_of_nodes.ts similarity index 93% rename from src/frontend/src/utils/node_editor/request_list_of_procedures.ts rename to src/frontend/src/utils/node_editor/request_list_of_nodes.ts index 5c32c7ae3..e3cdbbeac 100644 --- a/src/frontend/src/utils/node_editor/request_list_of_procedures.ts +++ b/src/frontend/src/utils/node_editor/request_list_of_nodes.ts @@ -2,7 +2,7 @@ import {CommandType, MeshInfo, Message, TargetType} from '../../flatbuffers/wsoc import * as flatbuffers from "flatbuffers"; import {webSocketHandler} from "../websocket_connector"; -export const request_list_of_procedures = () => { +export const request_list_of_nodes = () => { console.log('Querying server for mesh info'); let builder = new flatbuffers.Builder(1024); Message.startMessage(builder); diff --git a/src/frontend/src/utils/node_editor/run_sequence.ts b/src/frontend/src/utils/node_editor/run_sequence.ts new file mode 100644 index 000000000..cfdefd1a9 --- /dev/null +++ b/src/frontend/src/utils/node_editor/run_sequence.ts @@ -0,0 +1,3 @@ +export function run_sequence() { + console.log("Running sequence"); +} \ No newline at end of file diff --git a/src/frontend/src/utils/node_editor/update_list_of_procedures.ts b/src/frontend/src/utils/node_editor/update_nodes.ts similarity index 59% rename from src/frontend/src/utils/node_editor/update_list_of_procedures.ts rename to src/frontend/src/utils/node_editor/update_nodes.ts index 9a7fd1385..7440812ad 100644 --- a/src/frontend/src/utils/node_editor/update_list_of_procedures.ts +++ b/src/frontend/src/utils/node_editor/update_nodes.ts @@ -1,7 +1,7 @@ import {Message} from '../../flatbuffers/wsock'; import {useNodeEditorStore} from '../../state/useNodeEditorStore'; // Import the node editor Zustand store -export const update_list_of_procedures = (message: Message) => { +export const update_nodes = (message: Message) => { // Get the ProcedureStore from the received message const procedureStore = message.procedureStore(); if (!procedureStore) return; @@ -10,10 +10,36 @@ export const update_list_of_procedures = (message: Message) => { const proceduresLength = procedureStore.proceduresLength(); if (!proceduresLength) return; + const newNodes = []; // Create a list of nodes from the scene file objects + const server = message.server(); + if (server) { + const file_objects_length = server.allFileObjectsLength(); + if (file_objects_length) { + for (let i = 0; i < file_objects_length; i++) { + const fileObject = message.server()?.allFileObjects(i); + if (fileObject) { + // Create a new node for each file object + const node = { + id: `file-object-${i}`, // Unique node ID + type: 'input', + position: {x: 250, y: i * 100 - 100}, // Stagger positions vertically + data: { + label: fileObject.name(), + description: fileObject.fileType().toString(), + scriptFileLocation: fileObject.filepath(), + }, + }; + newNodes.push(node); + } + } + } + + + } // Create a list of nodes from the procedures - const newNodes = []; + for (let i = 0; i < proceduresLength; i++) { const procedure = procedureStore.procedures(i); if (procedure) { diff --git a/tests/core/comms/test_buffers.py b/tests/core/comms/test_buffers.py index f4837f831..73cc2dea9 100644 --- a/tests/core/comms/test_buffers.py +++ b/tests/core/comms/test_buffers.py @@ -25,10 +25,8 @@ def test_basic_flat_buffers(): scene=SceneDC( operation=SceneOperationsDC.REPLACE, current_file=FileObjectDC( - file_type=FileTypeDC.GLB, - purpose=FilePurposeDC.DESIGN, - filepath="/path/to/file.glb" - ) + file_type=FileTypeDC.GLB, purpose=FilePurposeDC.DESIGN, filepath="/path/to/file.glb" + ), ), mesh_info=MeshInfoDC(object_name="MyMeshObject", face_index=10), target_id=5678, @@ -56,10 +54,8 @@ def test_basic_flat_buffers_2(): scene=SceneDC( operation=SceneOperationsDC.ADD, current_file=FileObjectDC( - file_type=FileTypeDC.GLB, - purpose=FilePurposeDC.DESIGN, - filepath="/path/to/file.glb" - ) + file_type=FileTypeDC.GLB, purpose=FilePurposeDC.DESIGN, filepath="/path/to/file.glb" + ), ), mesh_info=MeshInfoDC(object_name="MyMeshObject", face_index=10), target_id=5678, @@ -94,6 +90,8 @@ def test_procedure_store(): description="Add stiffeners to the structure", parameters=[ParameterDC(name="ifc_file", type="pathlib.Path")], state=ProcedureStateDC.IDLE, + input_file_type=FileTypeDC.IFC, + export_file_type=FileTypeDC.IFC, ) ], ),