Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle custom types now used for Ros Messages and File paths #20

Merged
merged 25 commits into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,9 @@ module.exports = {
],
parserOptions: {
ecmaVersion: 'latest'
},
rules: {
'no-fallthrough': 1,
'no-inner-declarations': 1
}
}
21 changes: 10 additions & 11 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,20 @@ on:

jobs:
build:

runs-on: ubuntu-latest

strategy:
matrix:
node-version: [18.x, 19.x, 20.x]
node-version: [18.x, 20.x, 22.x, 23.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/

steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: 'yarn'
- run: yarn install
- run: yarn lint
- run: yarn build
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: 'yarn'
- run: yarn install
- run: yarn lint
- run: yarn build
16 changes: 11 additions & 5 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ import { useROSStore } from './stores/ros'
import { useMessasgeStore } from './stores/message'
import { usePackageStore } from './stores/package'
import { useNodesStore } from './stores/nodes'
import { computed, onMounted, ref, watch } from 'vue'
import { onMounted, ref, watch } from 'vue'
import PackageLoader from './components/PackageLoader.vue'
import type { Messages, NodeMsg, Packages, SubtreeInfo, TreeMsg } from './types/types'
import { EditorSkin, useEditorStore } from './stores/editor'
import type { MessageTypes, NodeMsg, Packages, SubtreeInfo, TreeMsg } from './types/types'
import { useEditorStore } from './stores/editor'
import { useEditNodeStore } from './stores/edit_node'
import NodeList from './components/NodeList.vue'
import SelectSubtree from './components/SelectSubtree.vue'
Expand Down Expand Up @@ -80,11 +80,11 @@ function updatePackagesSubscription() {
ros_store.packages_sub.subscribe(onNewPackagesMsg)
}

function onNewMessagesMsg(msg: Messages) {
function onNewMessagesMsg(msg: MessageTypes) {
if (!messages_store.messages_available) {
messages_store.areMessagesAvailable(true)
}
messages_store.updateAvailableMessages(msg.messages)
messages_store.updateAvailableMessages(msg)
}

function updateMessagesSubscription() {
Expand All @@ -107,6 +107,10 @@ function updateSubtreeInfoSubscription() {
ros_store.subtree_info_sub.subscribe(onNewSubtreeInfoMsg)
}

function updateChannelssubscription() {
ros_store.channels_sub.subscribe(messages_store.updateMessageChannels)
}

function handleNodeSearch(event: Event) {
const target = event.target as HTMLInputElement
node_search.value = target.value
Expand Down Expand Up @@ -154,6 +158,7 @@ ros_store.$onAction(({ name, after }) => {
updateTreeSubscription()
updateSubtreeInfoSubscription()
updateMessagesSubscription()
updateChannelssubscription()
updatePackagesSubscription()
})
})
Expand All @@ -163,6 +168,7 @@ onMounted(() => {
updateTreeSubscription()
updateSubtreeInfoSubscription()
updateMessagesSubscription()
updateChannelssubscription()
updatePackagesSubscription()
})
</script>
Expand Down
12 changes: 12 additions & 0 deletions src/assets/utils.scss
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,15 @@
--bs-btn-disabled-border-color: var(--bs-body-color);
--bs-gradient: none;
}

.search-results {
padding-left: 5px;
padding-right: 5px;

max-height: 11em;
overflow-y: auto;
}

.search-result:hover {
background-color: #007bff;
}
67 changes: 5 additions & 62 deletions src/components/D3BehaviorTreeEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -42,27 +42,19 @@ import type {
NodeDataLocation,
NodeMsg,
ParamData,
PyEnum,
PyLogger,
PyOperand,
PyOperator,
TreeMsg,
TrimmedNode,
TrimmedNodeData,
NodeDataWiring
} from '@/types/types'
import { Position, IOKind } from '@/types/types'
import { getDefaultValue, prettyprint_type, python_builtin_types, typesCompatible } from '@/utils'
import { faArrowDown19 } from '@fortawesome/free-solid-svg-icons'
import { getDefaultValue, prettyprint_type, serializeNodeOptions, typesCompatible } from '@/utils'
import { notify } from '@kyvg/vue3-notification'
import * as d3 from 'd3'
import type { ZoomBehavior } from 'd3'
import { onMounted, ref, watch, watchEffect } from 'vue'
import type { HierarchyNode, HierarchyLink } from 'd3-hierarchy'
import { flextree, type FlextreeNode } from 'd3-flextree'
import type { MoveNodeRequest, MoveNodeResponse } from '@/types/services/MoveNode'
import type { RemoveNodeRequest, RemoveNodeResponse } from '@/types/services/RemoveNode'
import type { ReplaceNodeRequest, ReplaceNodeResponse } from '@/types/services/ReplaceNode'
import type { WireNodeDataRequest, WireNodeDataResponse } from '@/types/services/WireNodeData'

const editor_store = useEditorStore()
Expand Down Expand Up @@ -152,67 +144,18 @@ function resetView() {
}

function buildNodeMessage(node: DocumentedNode): NodeMsg {
function getDefaultValues(paramList: NodeData[], options?: NodeData[] | null) {
options = options || []

return paramList.map((x) => {
return {
key: x.key,
value: getDefaultValue(prettyprint_type(x.serialized_value), options)
}
})
}
const default_options = getDefaultValues(node.options)
const options = default_options.map((x) => {
if (x.value.type === 'unset_optionref') {
const optionref: string = x.value.value as string
const optionTypeName = optionref.substring('Ref to "'.length, optionref.length - 1)
const optionType = default_options.find((x) => {
return x.key === optionTypeName
})
if (optionType && optionType.value) {
return {
key: x.key,
value: getDefaultValue(optionType.value.value as string)
}
}
}
const options = node.options.map((opt: NodeData) => {
return {
key: x.key,
value: x.value
key: opt.key,
value: getDefaultValue(prettyprint_type(opt.serialized_value), node.options)
} as ParamData
})

return {
module: node.module,
node_class: node.node_class,
name: node.name,
options: options.map((x) => {
const option: NodeData = {
key: x.key,
serialized_value: '',
serialized_type: ''
}
if (x.value.type === 'type') {
if (python_builtin_types.indexOf(x.value.value as string) >= 0) {
x.value.value = '__builtin__.' + x.value.value
}
option.serialized_value = JSON.stringify({
'py/type': x.value.value
})
} else if (x.value.type.startsWith('__')) {
const py_value: PyLogger | PyOperator | PyOperand | PyEnum = x.value.value as
| PyLogger
| PyOperator
| PyOperand
| PyEnum
py_value['py/object' as keyof typeof py_value] = x.value.type.substring('__'.length)
option.serialized_value = JSON.stringify(x.value.value)
} else {
option.serialized_value = JSON.stringify(x.value.value)
}
return option
}),
options: serializeNodeOptions(options),
child_names: [],
inputs: [],
outputs: [],
Expand Down
4 changes: 0 additions & 4 deletions src/components/EditableNode.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,12 @@
* POSSIBILITY OF SUCH DAMAGE.
-->
<script setup lang="ts">
import { useNodesStore } from '@/stores/nodes'
import type { DocumentedNode, ParamData } from '@/types/types'
import { computed } from 'vue'
import { getShortDoc } from '@/utils'
import { useEditorStore } from '@/stores/editor'
import { useEditNodeStore } from '@/stores/edit_node'
import ParamInputs from './ParamInputs.vue'
import ParamDisplay from './ParamDisplay.vue'

const nodes_store = useNodesStore()
const editor_store = useEditorStore()
const edit_node_store = useEditNodeStore()
</script>
Expand Down
75 changes: 0 additions & 75 deletions src/components/JSONInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,13 @@
-->
<script setup lang="ts">
import { useEditNodeStore } from '@/stores/edit_node'
import { useEditorStore } from '@/stores/editor'
import { useROSStore } from '@/stores/ros'
import type {
GetMessageFieldsRequest,
GetMessageFieldsResponse
} from '@/types/services/GetMessageFields'
import type { ParamData } from '@/types/types'
import { getMessageType } from '@/utils'
import { notify } from '@kyvg/vue3-notification'
import JSONEditor from 'jsoneditor'

import 'jsoneditor/dist/jsoneditor.min.css'
import { computed, onMounted, onUnmounted, ref, watch } from 'vue'

const editor_store = useEditorStore()
const edit_node_store = useEditNodeStore()
const ros_store = useROSStore()

const props = defineProps<{
category: 'options'
Expand All @@ -57,8 +47,6 @@ const param = computed<ParamData | undefined>(() =>
)

const is_valid = ref<boolean>(true)
const pyobjectstring = ref<string | undefined>(undefined)
const field_names = ref<string[]>([])

const editor_ref = ref<HTMLDivElement>()
let editor: JSONEditor | undefined = undefined
Expand All @@ -80,68 +68,6 @@ function handleChange() {
}
}

//TODO maybe this would be better placed in the getDefaultValue utility function
function updateMessageType() {
if (param.value === undefined) {
return
}

// Trim the leading '__' that is sometimes added
let message_type: string
if (param.value.value.type.startsWith('__')) {
message_type = param.value.value.type.substring('__'.length)
} else {
message_type = param.value.value.type
}

const message = getMessageType(message_type)
if (message.msg === '/dict' || message.msg === '') {
/*notify({
title: 'Cannot request message infos!',
text: 'Message is a dict not a ROS message!',
type: 'warn'
})*/
return
} else {
ros_store.get_message_fields_service.callService(
{
message_type: message.msg,
service: message.service,
action: message.action,
type: message.type
} as GetMessageFieldsRequest,
(response: GetMessageFieldsResponse) => {
if (response.success) {
pyobjectstring.value = response.fields
field_names.value = response.field_names

const new_value = JSON.parse(response.fields)
console.log(new_value)

if (editor === undefined) {
return
}
editor.update(new_value)
handleChange()
} else {
notify({
title: 'GetMessageFields Service Error',
text: response.error_message,
type: 'error'
})
}
},
(failed) => {
notify({
title: 'Failure calling GetMessageFields Service',
text: failed,
type: 'error'
})
}
)
}
}

// This fires when param type changes and updates the editor accordingly
watch(
() => {
Expand All @@ -155,7 +81,6 @@ watch(
return
}
editor.update(param.value.value.value)
updateMessageType()
}
)

Expand Down
1 change: 0 additions & 1 deletion src/components/MultipleSelection.vue
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,6 @@ function saveSubtree(tree: TreeMsg) {
<template>
<SelectLocationModal
v-model="show_selection_modal"
title="Select Save Location"
@close="show_selection_modal = false"
@select="setSaveLocation"
/>
Expand Down
Loading
Loading