2012-09-09 14 views
8

Tôi đang viết một trình soạn thảo đồ họa cho một "mô hình" (tức là một tập hợp các hộp và các dòng với một số ngữ nghĩa, chẳng hạn như UML, chi tiết không quan trọng ở đây) . Vì vậy, tôi muốn có một cấu trúc dữ liệu đại diện cho mô hình, và một sơ đồ nơi chỉnh sửa biểu đồ gây ra một sự thay đổi tương ứng trong mô hình. Vì vậy, nếu, ví dụ, một phần tử mô hình có một số văn bản trong một thuộc tính, và tôi chỉnh sửa văn bản trong sơ đồ, tôi muốn phần tử mô hình được cập nhật.Cấu trúc dữ liệu Zipper cho trình soạn thảo mô hình đồ họa

Mô hình có thể sẽ được biểu diễn dưới dạng cây, nhưng tôi muốn người biên tập biểu đồ biết rất ít về mô hình đại diện nhất có thể. (Tôi đang sử dụng khung làm việc diagrams, vì vậy việc liên kết thông tin tùy ý với phần tử đồ họa thật dễ dàng). Có thể sẽ có một lớp "mô hình" để mã hóa giao diện, nếu tôi chỉ có thể tìm ra những gì nên được.

Nếu tôi đã làm điều này bằng ngôn ngữ bắt buộc, nó sẽ đơn giản: Tôi chỉ có một tham chiếu từ phần tử đồ họa trong sơ đồ trở lại phần tử mô hình. Về lý thuyết, tôi vẫn có thể làm điều này bằng cách xây dựng mô hình từ một bộ sưu tập lớn các IORef, nhưng đó sẽ là viết một chương trình Java trong Haskell.

Rõ ràng, mỗi phần tử đồ họa sẽ có một số loại cookie được liên kết với nó sẽ cho phép cập nhật mô hình xảy ra. Một câu trả lời đơn giản là cung cấp cho mỗi phần tử mô hình một mã định danh duy nhất và lưu mô hình trong bảng tra cứu Data.Map. Nhưng điều đó yêu cầu sổ sách kế toán đáng kể để đảm bảo rằng không có hai yếu tố mô hình nào nhận được cùng một số nhận dạng. Nó cũng tấn công tôi như một giải pháp "stringly typed"; bạn phải xử lý các trường hợp một đối tượng bị xóa nhưng có một tham chiếu treo lơ lửng ở nơi khác, và khó có thể nói bất cứ điều gì về cấu trúc bên trong của mô hình trong các loại của bạn.

Mặt khác, Oleg's writings về khóa kéo có nhiều lỗ và con trỏ với chia sẻ giao dịch rõ ràng giống như một lựa chọn tốt hơn, nếu chỉ tôi mới có thể hiểu được. Tôi có được ý tưởng cơ bản về danh sách và các khóa kéo của cây và sự khác biệt của một cấu trúc dữ liệu. Nó sẽ có thể cho mọi phần tử trong một sơ đồ để giữ con trỏ vào một dây kéo của mô hình? Vì vậy, nếu một thay đổi được thực hiện thì nó có thể được cam kết với tất cả các con trỏ khác? Bao gồm các hoạt động của cây (chẳng hạn như di chuyển cây con từ nơi này sang nơi khác)? Nó sẽ đặc biệt giúp tôi vào thời điểm này nếu có một số loại hướng dẫn về tiếp tục phân cách, và giải thích về cách chúng làm cho dây kéo đa con trỏ của Oleg hoạt động, hơi dốc hơn so với bài đăng của Oleg?

+1

Có thể blog của Chung-chieh Shan? : http://conway.rutgers.edu/~ccshan/wiki/blog/posts/WalkZip1/. Lưu ý, Blobs (wxHaskell) là một thư viện để viết "biên tập viên mạng" - nó có thể có chút phân đoạn nhưng có thể ít công việc để cập nhật nó hơn là bắt đầu lại với Sơ đồ. –

+0

Cảm ơn. Tôi đã bắt đầu làm việc thông qua nó. Tôi sẽ cho bạn biết nếu nó dẫn đến một câu trả lời. –

Trả lời

2

Tôi nghĩ bạn hiện đang làm việc từ một thiết kế trong đó mỗi nút trong cây mô hình được trình bày bởi một tiện ích đồ họa riêng biệt và mỗi tiện ích con có thể cập nhật mô hình độc lập. Nếu vậy, tôi không tin rằng một dây kéo nhiều lỗ sẽ rất thiết thực. Vấn đề là sự phức tạp của dây kéo phát triển nhanh chóng với số lượng lỗ mà bạn muốn hỗ trợ. Khi bạn nhận được nhiều hơn 2 thuật ngữ, kích thước của dây kéo sẽ nhận được khá lớn. Từ quan điểm khác biệt, một dây kéo 2 lỗ là dây kéo trên dây kéo 1 lỗ, do đó độ phức tạp tăng theo hoạt động của quy tắc chuỗi.

Thay vào đó, bạn có thể mượn ý tưởng từ MVC. Mỗi nút vẫn được liên kết với một tiện ích, nhưng chúng không giao tiếp trực tiếp. Thay vào đó họ đi qua một bộ điều khiển trung gian, duy trì một dây kéo duy nhất. Khi các tiện ích được cập nhật, chúng sẽ thông báo cho bộ điều khiển, sẽ tuần tự hóa tất cả các bản cập nhật và sửa đổi dây kéo cho phù hợp.

Các tiện ích sẽ vẫn cần một số loại số nhận dạng để tham chiếu các nút mô hình. Tôi đã tìm thấy thường dễ nhất để sử dụng đường dẫn của nút, ví dụ: [0] cho thư mục gốc, [1,0] cho con thứ hai của root, v.v. Điều này có một số lợi thế. Thật dễ dàng để xác định nút một đường dẫn đề cập đến, và nó cũng dễ dàng cho một dây kéo để tính toán đường đi ngắn nhất từ ​​vị trí hiện tại đến một nút nhất định.Đối với cấu trúc cây, chúng cũng là duy nhất để xóa và chèn lại. Ngay cả đó thường không phải là một vấn đề bởi vì, khi bộ điều khiển được thông báo rằng các nút sẽ bị xóa, nó có thể xóa các widget tương ứng và bỏ qua bất kỳ cập nhật liên quan nào. Miễn là tuổi thọ của tiện ích được gắn liền với thời gian tồn tại của mỗi nút, đường dẫn sẽ đủ độc đáo để xác định mọi sửa đổi.

Đối với hoạt động của cây, có thể tôi sẽ hủy sau đó tạo lại các tiện ích đồ họa.

Ví dụ: tôi có một số mã mà does this sort of thing. Trong mô hình này không có các widget riêng biệt cho mỗi nút, thay vào đó tôi render mọi thứ bằng cách sử dụng các biểu đồ, sau đó truy vấn sơ đồ dựa trên vị trí nhấn để lấy đường dẫn vào mô hình dữ liệu. Nó hoàn toàn xa xôi, và tôi đã không xem xét nó trong một thời gian, vì vậy nó có thể không xây dựng, nhưng mã có thể cung cấp cho bạn một số ý tưởng.

+0

Điều về phiên bản của khóa kéo của Oleg là nó không liên quan đến việc phân biệt cấu trúc dữ liệu, mà là sử dụng tiếp tục để chụp một phần đi bộ. –

+0

@PaulJohnson - Ngay cả với việc tiếp tục chụp một phần đi bộ, vẫn có cùng số trạng thái được biểu diễn, đó là nơi mà sự phức tạp xuất phát. Nó được quản lý khác nhau bởi vì Oleg sử dụng một thứ tự rõ ràng giữa các lần tiếp tục, có nghĩa là bạn phải quản lý sự phức tạp bằng cách đảm bảo các tiếp tục được cập nhật theo thứ tự thích hợp. Tôi không chắc cái nào đơn giản hơn trong thực tế, nhưng tôi hy vọng một trong hai cách tiếp cận là không tầm thường. –

Các vấn đề liên quan