Skip to content
彭大海 edited this page Jun 7, 2025 · 1 revision

MbcWJFX 專案資料結構詳細解析

核心資料結構

1. 基本點結構 (Point)

vpl.h 中定義的基本座標結構:

struct Point{
	UInt16 x;
	UInt16 y;
};

這個結構用於表示螢幕上的座標位置,被廣泛應用於各種元素的位置和大小定義。

2. IO節點 (IONODE)

struct IONODE{
	UInt16 ID;
	UInt16 TYPE;                    // 1 = input, 0 = output, 2 = drag point
	Boolean NotReady;
	void *P;                        // 指向數據的指針
	UInt16 BYTES;                   // 數據大小
	UInt16 NUMS;                    // 數據數量
	struct Point TL;                // 左上角座標
	struct Point EXT;               // 尺寸
	struct IONODE *PREV;            // 鏈表前一個節點
	struct IONODE *NEXT;            // 鏈表下一個節點
};
typedef struct IONODE *IONODEP;

IO節點代表區塊的輸入/輸出點:

  • TYPE:定義節點類型(輸入、輸出或拖曳點)
  • NotReady:標記數據是否準備好
  • P:指向實際數據的指針
  • PREV/NEXT:形成雙向鏈表結構

3. 控制節點 (CTRLNODE)

struct CTRLNODE{
	UInt16 ID;
	struct Point TL;                // 左上角座標
	struct Point EXT;               // 尺寸
	struct CTRLNODE *PREV;          // 鏈表前一個節點
	struct CTRLNODE *NEXT;          // 鏈表下一個節點
};
typedef struct CTRLNODE *CTRLNODEP;

控制節點用於前面板上的交互元素,如按鈕、開關等。

4. 區塊外觀 (BA/PA)

typedef struct {
	UInt16 BITMAPID;               // 位圖資源ID
	struct Point XY;                // 位置
	struct Point SIZE;              // 大小
	IONODEP IONodeLLHead;           // IO節點鏈表頭
	int INodeNUM;                   // 輸入節點數量
	int ONodeNUM;                   // 輸出節點數量
	CTRLNODEP CTRLNodeLLHead;       // 控制節點鏈表頭
	Boolean DrawBorder;             // 是否繪製邊框
	Boolean ReDraw;                 // 是否需要重繪
	Boolean Clean;                  // 清理標記
}BA;
typedef BA *BAP;

typedef struct {
	UInt16 BITMAPID;               // 位圖資源ID
	struct Point XY;                // 位置
	struct Point SIZE;              // 大小
	CTRLNODEP CTRLNodeLLHead;       // 控制節點鏈表頭
	Boolean ReDraw;                 // 是否需要重繪
}PA;
typedef PA *PAP;
  • BA:區塊圖表中區塊的外觀和屬性
  • PA:前面板中控制元件的外觀和屬性

5. 區塊節點 (BlockNode)

struct BlockNode{
	UInt16 ID;                      // 區塊ID
	UInt16 TYPE;                    // 區塊類型
	BAP bap;                        // 區塊外觀
	PAP pap;                        // 面板外觀
	Ptr LoopBlockHOOKP;             // 迴圈區塊指針
	Ptr CaseBlockHOOKLLHeadP;       // Switch case 鏈表頭
	Ptr CurrentHOOKP;               // 當前 case 指針
	Ptr hookP;                      // 子區塊指針
	char *filename;                 // 檔案名稱
	struct BlockNode *SelfBlockLLHead;      // 自身區塊鏈表頭
	struct BlockNode *BackgroundBlockLLHead; // 背景區塊鏈表頭
	struct BlockNode *PREVNODE;              // 前一個節點
	struct BlockNode *NEXTNODE;              // 下一個節點
};

typedef struct BlockNode BN;
typedef BN *BNP;

區塊節點是整個系統的核心,代表程式中的功能區塊:

  • TYPE:區塊類型(HOOKBLOCK、FUNCBLOCK、LOOPBLOCK、CASEBLOCK等)
  • bap/pap:區塊在區塊圖和前面板的外觀
  • 各種指針用於實現複雜的程式結構(迴圈、條件等)
  • 鏈表結構用於管理區塊之間的關係

6. 線路節點 (wList)

struct wList{
	UInt16 WireID;                  // 線路ID
	BNP StartBlockP;                // 起始區塊指針
	IONODEP StartNodeP;             // 起始IO節點指針
	BNP EndBlockP;                  // 終止區塊指針
	IONODEP EndNodeP;               // 終止IO節點指針
	Boolean DIRTY;                  // 髒標記
	Boolean STARTRUN;               // 開始執行標記
	struct Point RUNPOINT;          // 執行點位置
	int RUNSEG;                     // 執行段
	struct wList* PREVNODE;          // 前一個節點
	struct wList* NEXTNODE;          // 下一個節點
};

typedef struct wList WN;
typedef WN *WNP;

線路節點表示連接區塊的線路:

  • 記錄起始和終止的區塊及IO節點
  • 包含執行狀態相關的標記和位置
  • 形成雙向鏈表結構

7. 端點結構 (EndPoint)

typedef struct{
	BNP BlockP;                     // 區塊指針
	IONODEP NodeP;                  // IO節點指針
}EndPoint;

端點結構用於表示線路的連接點,包含區塊和IO節點的引用。

8. HOOK結構

struct HOOK{
	char *name;                     // 名稱
	BNP BlockLLHeadP;               // 區塊鏈表頭
	WNP WireLLHeadP;                // 線路鏈表頭
	struct HOOK *PREV;              // 前一個HOOK
	struct HOOK *NEXT;              // 下一個HOOK
};
typedef struct HOOK HOOKNODE;
typedef HOOKNODE *HOOKP;

HOOK結構是一個容器,管理一組相關的區塊和線路:

  • 用於實現子程式、迴圈體、條件分支等
  • 包含自己的區塊和線路鏈表
  • 形成雙向鏈表結構

資料結構之間的關係

  1. 區塊與IO節點:每個區塊(BlockNode)通過其 bap->IONodeLLHead 維護一個IO節點鏈表,表示該區塊的輸入/輸出點。

  2. 區塊與控制節點:區塊通過 bap->CTRLNodeLLHeadpap->CTRLNodeLLHead 維護控制節點鏈表,用於用戶交互。

  3. 線路與端點:線路(wList)連接兩個端點(EndPoint),每個端點包含一個區塊和一個IO節點的引用。

  4. HOOK與區塊/線路:HOOK結構作為容器,管理一組相關的區塊和線路,用於實現複雜的程式結構。

  5. 區塊之間的層次關係:通過 SelfBlockLLHeadBackgroundBlockLLHead 等指針,建立區塊之間的層次關係,支持嵌套結構。

資料流動機制

在執行時,系統通過以下步驟處理資料流:

  1. 檢查所有區塊的IO節點狀態(NotReady 標記)
  2. 對於輸入節點已準備好的區塊,執行其功能(在 run.c 中的 DoItemRUN 函數)
  3. 更新區塊的輸出節點數據
  4. 通過線路將數據從輸出節點傳遞到連接的輸入節點
  5. 重複此過程直到所有數據流動完成

這種資料結構設計使得 MbcWJFX 能夠實現類似 LabVIEW 的數據流編程模型,支持複雜的程式邏輯和控制流程。