Selaa lähdekoodia

add addressspace ref to basenode

Martin Kunz 1 vuosi sitten
vanhempi
commit
d6a8715c99

+ 3 - 1
src/components/TheContextMenu.vue

@@ -1,6 +1,7 @@
 <script setup lang="ts">
 import { coerceNodeId } from '@/ua/NodeId';
 import { UABaseNode } from '@/ua/UABaseNode';
+import { assert } from '@/util/assert';
 import { useStore } from '@/util/store';
 import { ref, reactive, onMounted, onUnmounted, computed, type CSSProperties } from 'vue';
 
@@ -19,7 +20,8 @@ const closeMenu = () => {
 };
 
 const newInstance = () => {
-    store.selectedNode = new UABaseNode({browseName: "new node", nodeId: coerceNodeId("ns=0;i=999999")});
+    assert(store.addressSpace!=null)
+    store.selectedNode = new UABaseNode({browseName: "new node", addressSpace: store.addressSpace, nodeId: coerceNodeId("ns=0;i=999999")});
     closeMenu();
 };
 

+ 5 - 4
src/components/TheModels.vue

@@ -7,6 +7,7 @@ import { ref } from 'vue';
 import VDialog from './VDialog.vue'
 import JSZip from "jszip";
 import YAML from 'yaml'
+import { assert } from '@/util/assert';
 
 const store = useStore()
 const newDialogOpen = ref(false);
@@ -70,7 +71,8 @@ async function handleDrop(e: DragEvent) {
   else {
     for (const file of e.dataTransfer.files) {
       const xmlString = await file.text();
-      store.addNodeset(await UANodeSet.parse(xmlString, file.name));
+      assert(store.addressSpace!=null);
+      store.addNodeset(await UANodeSet.parse(xmlString, file.name, store.addressSpace));
     }
   }
 }
@@ -78,11 +80,10 @@ async function handleDrop(e: DragEvent) {
 async function  loadZip(file: File){
   const zip= await JSZip.loadAsync(file.arrayBuffer())
   const filenames=JSON.parse(await zip.files['project.json'].async("string"));
-  let nodesets: UANodeSet[]=[];
+  const as=new AddressSpace([]);
   for(const fileName of filenames) {
-    nodesets.push(await UANodeSet.parse(await zip.files[fileName].async("string"), fileName));
+    as.addNodeset(await UANodeSet.parse(await zip.files[fileName].async("string"), fileName, as));
   }
-  const as=new AddressSpace(nodesets);
   const mlist=YAML.parse(await zip.files['mapping.yaml'].async("string")) as IMappingValue[];
   const mapping=new Map<string, IMappingValue>();
   for(const entry of mlist) {

+ 1 - 2
src/components/TheParent.vue

@@ -5,7 +5,6 @@ import TheTreeDialog from './TheTreeDialog.vue';
 import { UABaseNode } from '@/ua/UABaseNode';
 import { ReferenceTypeIds } from '@/ua/opcua_node_ids';
 import type { UAReferenceType } from '@/ua/UAReferenceType';
-import { NodeId } from '@/ua/NodeId';
 const store = useStore()
 
 const parentDialogOpen = ref(false);
@@ -13,7 +12,7 @@ const node = computed(() => {
   return store.selectedNode;
 });
 const selectedRefType = ref('')
-const selectedParent = ref(new UABaseNode({browseName: "", nodeId:NodeId.nullNodeId}));
+const selectedParent = ref(UABaseNode.nullBaseNode);
 
 function clickNode(clickedNode: UABaseNode) {
   selectedParent.value=clickedNode;

+ 9 - 11
src/ua/AddressSpace.ts

@@ -3,9 +3,9 @@ import { UABaseNode } from "./UABaseNode";
 import { NamespaceTable } from "./NameSpaceTable";
 import YAML from 'yaml'
 import JSZip from "jszip";
+import { type IAddressSpace } from "./IAddressSpace";
 
-
-export class AddressSpace{
+export class AddressSpace implements IAddressSpace{
 
     nodeMap:  Map<string, UABaseNode>;
     nst: NamespaceTable;
@@ -27,10 +27,6 @@ export class AddressSpace{
         return this.nodeMap.get(nodeId)
     }
 
-    public getHierarchicalReferenceTypes() {
-
-    }
-
     public getSubTreeAsList(nodeId: string): UABaseNode[] {
         const node=this.findNode(nodeId);
         if(!node)
@@ -54,15 +50,15 @@ export class AddressSpace{
     }
 
     static async load(files: string[]) {
+        const as=new AddressSpace([]);
         const promises:Promise<UANodeSet>[] = []
         for(const file of files) {
-            promises.push(UANodeSet.load(file));
+            promises.push(UANodeSet.load(file, as));
         }
-        const sets:UANodeSet[]= [];
         for(const p of promises) {
-            sets.push(await p)
+            as.addNodeset(await p);
         }
-        return new AddressSpace(sets);
+        return as;
     }
 
     public exportProject() {
@@ -83,4 +79,6 @@ export interface IMappingValue {
     path: string;
     read: string;
     write: string;
-  }
+  }
+
+

+ 14 - 7
src/ua/UABaseNode.ts

@@ -8,11 +8,16 @@ import { UAExtension } from "./UAExtension";
 import { UAUserWriteMask } from "./UAUserWriteMask";
 import { UAWriteMask } from "./UAWriteMask";
 import { UAAccessRestriction } from "./UAAccessRestriction";
+import { type IAddressSpace } from "./IAddressSpace";
 export class UABaseNode implements IToXML{
 
+    public static nullBaseNode=new UABaseNode({browseName: "", addressSpace: {} as IAddressSpace, nodeId: NodeId.nullNodeId});
+
+
     public nodeId: NodeId;
     public nodeClass="UABaseNode";
     public browseName: string;
+    public addressSpace?: IAddressSpace
     public displayName?: string; //LocText
     public description?: string; //LocText
     public symbolicName?: string; //SymbolicName
@@ -26,17 +31,16 @@ export class UABaseNode implements IToXML{
     public rolePermissions: UARolePermission[]=[]; 
     public extensions: UAExtension[]=[];
     public references: UAReference[]=[];
-    public opts: string[]=[];
-    
+    public opts: string[]=[]; 
     
     constructor(options: UABaseNodeOptions) {
         this.nodeId=options.nodeId;
         this.browseName=options.browseName;
+        this.addressSpace=options.addressSpace;
         this.displayName=options.displayName;
         this.references=options.references||[];     
     }
 
-    public static nullBaseNode=new UABaseNode({browseName: "", nodeId: NodeId.nullNodeId});
 
     reIndex(nst: NamespaceTable, onst: NamespaceTable) {
         const nsName=onst.getUri(this.nodeId.namespace);
@@ -137,7 +141,7 @@ export class UABaseNode implements IToXML{
 
 
 
-    static fromXML(xmlObject: any): UABaseNode{
+    static fromXML(xmlObject: any, addressSpace: IAddressSpace): UABaseNode{
         const xmlReferences=xmlObject['References']||[];
         const references:UAReference[]=[];
         const nodeId=coerceNodeId(xmlObject['@_NodeId']);
@@ -147,7 +151,9 @@ export class UABaseNode implements IToXML{
         const ua=new UABaseNode({nodeId: nodeId,
                                 browseName: xmlObject['@_BrowseName'], 
                                 displayName: xmlObject['DisplayName']['#text'], 
-                                references: references}); 
+                                references: references,
+                                addressSpace: addressSpace
+                            }); 
 
 
         return ua;
@@ -171,9 +177,10 @@ export class UABaseNode implements IToXML{
 
 export interface UABaseNodeOptions {
     browseName: string;
-    namespace?: string;
     nodeId: NodeId;
+    namespace?: string;
     references?: UAReference[];
     displayName?: string;
-    description?: string
+    description?: string;
+    addressSpace: IAddressSpace;
 }

+ 5 - 3
src/ua/UAMethod.ts

@@ -1,6 +1,7 @@
 import { XMLElem } from "@/util/XmlElem";
 import { UABaseNode, type UABaseNodeOptions } from "./UABaseNode";
 import type { NamespaceTable } from "./NameSpaceTable";
+import type { AddressSpace } from "./AddressSpace";
 
 export class UAMethod extends UABaseNode {
     constructor(options: UAMethodNodeOptions) {
@@ -8,12 +9,13 @@ export class UAMethod extends UABaseNode {
                     this.nodeClass="Method";
     }
 
-    static  fromXML(uaMethod: any): UAMethod{
-        const bn=super.fromXML(uaMethod)
+    static  fromXML(uaMethod: any, addressSpace: AddressSpace): UAMethod{
+        const bn=super.fromXML(uaMethod, addressSpace)
         return new UAMethod({nodeId: bn.nodeId, 
                             browseName: bn.browseName, 
                             displayName: bn.displayName,
-                            references: bn.references});
+                            references: bn.references,
+                            addressSpace: addressSpace});
     }
 
     toXML(lnst:NamespaceTable, gnst:NamespaceTable): XMLElem {

+ 10 - 9
src/ua/UANodeSet.ts

@@ -9,6 +9,7 @@ import { XMLElem, type IToXML } from '@/util/XmlElem';
 import { UAReferenceType } from './UAReferenceType';
 import { UAObjectType } from './UAObjectType';
 import { UAVariableType } from './UAVariableType';
+import type { AddressSpace } from './AddressSpace';
 
 export class UANodeSet implements IToXML{
 
@@ -53,12 +54,12 @@ export class UANodeSet implements IToXML{
         return xmlUANodeSet;
     }
 
-    static async load(url: string): Promise<UANodeSet> {
+    static async load(url: string, addressSpace: AddressSpace): Promise<UANodeSet> {
         const xml= await (await fetch(url)).text();
         const fileName= url.split('/').pop()||url
-        return this.parse(xml, fileName);
+        return this.parse(xml, fileName, addressSpace);
     }
-    static async parse(xml: string, fileName: string): Promise<UANodeSet> {
+    static async parse(xml: string, fileName: string, addressSpace: AddressSpace): Promise<UANodeSet> {
         const parseOptions:Partial<X2jOptions>={
             ignoreAttributes: false,
             alwaysCreateTextNode: true, //force consistent result
@@ -96,27 +97,27 @@ export class UANodeSet implements IToXML{
         const nodes:UABaseNode[]=[];
         const xmlObjects=xmlObj['UANodeSet']['UAObject']||[];
         for(const xmlObject of xmlObjects) {
-            nodes.push(UAObject.fromXML(xmlObject));
+            nodes.push(UAObject.fromXML(xmlObject, addressSpace));
         }
         const xmlVariables=xmlObj['UANodeSet']['UAVariable']||[];
         for(const xmlVariable of xmlVariables) {
-            nodes.push(UAVariable.fromXML(xmlVariable));
+            nodes.push(UAVariable.fromXML(xmlVariable, addressSpace));
         }
         const xmlMethods=xmlObj['UANodeSet']['UAMethod']||[];
         for(const xmlMethod of xmlMethods) {
-            nodes.push(UAMethod.fromXML(xmlMethod));
+            nodes.push(UAMethod.fromXML(xmlMethod, addressSpace));
         }
         const xmlReferenceTypes=xmlObj['UANodeSet']['UAReferenceType']||[];
         for(const xmlReferenceType of xmlReferenceTypes) {
-            nodes.push(UAReferenceType.fromXML(xmlReferenceType));
+            nodes.push(UAReferenceType.fromXML(xmlReferenceType, addressSpace));
         }
         const xmlObjectTypes=xmlObj['UANodeSet']['UAObjectType']||[];
         for(const xmlObjectType of xmlObjectTypes) {
-            nodes.push(UAObjectType.fromXML(xmlObjectType));
+            nodes.push(UAObjectType.fromXML(xmlObjectType, addressSpace));
         }
         const xmlVariableTypes=xmlObj['UANodeSet']['UAVariableType']||[];
         for(const xmlVariableType of xmlVariableTypes) {
-            nodes.push(UAVariableType.fromXML(xmlVariableType));
+            nodes.push(UAVariableType.fromXML(xmlVariableType, addressSpace));
         }
         const uaNamespaceUris=xmlObj['UANodeSet']['NamespaceUris']||[];
         const nst=new NamespaceTable();

+ 6 - 7
src/ua/UAObject.ts

@@ -1,9 +1,7 @@
 import { XMLElem } from "@/util/XmlElem";
-import { UABaseNode, type UABaseNodeOptions } from "./UABaseNode";
 import type { NamespaceTable } from "./NameSpaceTable";
-
-
-
+import { UABaseNode, type UABaseNodeOptions } from "./UABaseNode";
+import type { IAddressSpace } from "./IAddressSpace";
 
 
 export class UAObject extends UABaseNode {
@@ -14,12 +12,13 @@ export class UAObject extends UABaseNode {
                     this.nodeClass="Object";
     }
 
-    static  fromXML(uaObject: any): UAObject{
-        const bn=super.fromXML(uaObject)
+    static  fromXML(uaObject: any, addressSpace: IAddressSpace): UAObject{
+        const bn=super.fromXML(uaObject, addressSpace)
         return new UAObject({nodeId: bn.nodeId, 
                             browseName: bn.browseName, 
                             displayName: bn.displayName,
-                            references: bn.references});
+                            references: bn.references,
+                            addressSpace: addressSpace});
     }
 
     toXML(lnst:NamespaceTable, gnst:NamespaceTable): XMLElem {

+ 5 - 3
src/ua/UAObjectType.ts

@@ -1,6 +1,7 @@
 import { XMLElem } from "@/util/XmlElem";
 import type { NamespaceTable } from "./NameSpaceTable";
 import { UABaseNode, type UABaseNodeOptions } from "./UABaseNode";
+import type { AddressSpace } from "./AddressSpace";
 
 
 
@@ -14,13 +15,14 @@ export class UAObjectType extends UABaseNode{
         this.isAbstract=options.isAbstract||false;
     }
 
-    static  fromXML(xmlObjType: any): UAObjectType{
-        const bn=super.fromXML(xmlObjType)
+    static  fromXML(xmlObjType: any, addressSpace: AddressSpace): UAObjectType{
+        const bn=super.fromXML(xmlObjType, addressSpace)
         return new UAObjectType({nodeId: bn.nodeId, 
                             browseName: bn.browseName, 
                             displayName: bn.displayName,
                             references: bn.references,
-                            isAbstract: xmlObjType['@_IsAbstract']==='true'});
+                            isAbstract: xmlObjType['@_IsAbstract']==='true',
+                            addressSpace: addressSpace});
     }
 
     toXML(lnst:NamespaceTable, gnst:NamespaceTable): XMLElem {

+ 5 - 3
src/ua/UAReferenceType.ts

@@ -1,6 +1,7 @@
 import { XMLElem } from "@/util/XmlElem";
 import type { NamespaceTable } from "./NameSpaceTable";
 import { UABaseNode, type UABaseNodeOptions } from "./UABaseNode";
+import type { AddressSpace } from "./AddressSpace";
 
 export class UAReferenceType extends UABaseNode{
     public isAbstract: boolean;
@@ -10,13 +11,14 @@ export class UAReferenceType extends UABaseNode{
         this.isAbstract=options.isAbstract||false;
     }
 
-    static  fromXML(xmlRefType: any): UAReferenceType{
-        const bn=super.fromXML(xmlRefType)
+    static  fromXML(xmlRefType: any, addressSpace: AddressSpace): UAReferenceType{
+        const bn=super.fromXML(xmlRefType, addressSpace)
         return new UAReferenceType({nodeId: bn.nodeId, 
                             browseName: bn.browseName, 
                             displayName: bn.displayName,
                             references: bn.references,
-                            isAbstract: xmlRefType['@_IsAbstract']==='true'});
+                            isAbstract: xmlRefType['@_IsAbstract']==='true',
+                            addressSpace: addressSpace});
     }
 
     toXML(lnst:NamespaceTable, gnst:NamespaceTable): XMLElem {

+ 5 - 3
src/ua/UAVariable.ts

@@ -1,6 +1,7 @@
 import { XMLElem } from "@/util/XmlElem";
 import { UABaseNode, type UABaseNodeOptions } from "./UABaseNode";
 import type { NamespaceTable } from "./NameSpaceTable";
+import type { AddressSpace } from "./AddressSpace";
 
 
 
@@ -12,12 +13,13 @@ export class UAVariable extends UABaseNode {
                     this.nodeClass="Variable";
     }
 
-    static  fromXML(uaObject: any): UAVariable{
-        const bn=super.fromXML(uaObject)
+    static  fromXML(uaObject: any, addressSpace: AddressSpace): UAVariable{
+        const bn=super.fromXML(uaObject, addressSpace)
         return new UAVariable({nodeId: bn.nodeId, 
                                 browseName: bn.browseName, 
                                 displayName: bn.displayName, 
-                                references: bn.references});
+                                references: bn.references,
+                                addressSpace: addressSpace});
     }
 
     toXML(lnst:NamespaceTable, gnst:NamespaceTable): XMLElem {

+ 5 - 3
src/ua/UAVariableType.ts

@@ -1,6 +1,7 @@
 import { XMLElem } from "@/util/XmlElem";
 import type { NamespaceTable } from "./NameSpaceTable";
 import { UABaseNode, type UABaseNodeOptions } from "./UABaseNode";
+import type { AddressSpace } from "./AddressSpace";
 
 export class UAVariableType extends UABaseNode{
     public isAbstract: boolean;
@@ -13,13 +14,14 @@ export class UAVariableType extends UABaseNode{
  
     }
 
-    static  fromXML(xmlObjType: any): UAVariableType{
-        const bn=super.fromXML(xmlObjType)
+    static  fromXML(xmlObjType: any, addressSpace: AddressSpace): UAVariableType{
+        const bn=super.fromXML(xmlObjType, addressSpace)
         return new UAVariableType({nodeId: bn.nodeId, 
                             browseName: bn.browseName, 
                             displayName: bn.displayName,
                             references: bn.references,
-                            isAbstract: xmlObjType['@_IsAbstract']==='true'});
+                            isAbstract: xmlObjType['@_IsAbstract']==='true',
+                            addressSpace: addressSpace});
     }
 
     toXML(lnst:NamespaceTable, gnst:NamespaceTable): XMLElem {

+ 2 - 2
src/util/bi-map.ts

@@ -6,8 +6,8 @@
  * @since v0.1.0
  */
 export class BiMap<K = any, V = any> {
-	private primaryMap: Map<K, V>;
-	private secondaryMap: Map<V, K>;
+	public primaryMap: Map<K, V>;
+	public secondaryMap: Map<V, K>;
 	
 	public constructor() {
 		this.primaryMap = new Map<K, V>();

+ 1 - 1
src/util/store.ts

@@ -1,5 +1,5 @@
 import { AddressSpace } from '@/ua/AddressSpace'
-import { UABaseNode } from '@/ua/UABaseNode'
+import { type UABaseNode } from '@/ua/UABaseNode'
 import type { UANodeSet } from '@/ua/UANodeSet'
 import { defineStore } from 'pinia'
 import { ref } from 'vue'