Skip to content

Các khái niệm (Concepts)

Pham Tien Dzung edited this page Apr 9, 2021 · 8 revisions

Private Data Flow and Global Data Flow

Với dạng game là gamehub, chứa nhiều minigame bên trong một khối hoặc một game lớn, thì đôi khi các luồng dữ liệu không cần thiết phải chia sẻ ra bên ngoài hay từ bên ngoài game lớn (lobby) cập nhật vào các thành phần bên trong game mini. Như vậy, cần phải quản lý và phân tách riêng biệt giữa các luồng data cho game độc lập với luồng data chung.

Để giải quyết vấn đề luồng dữ liệu độc lập và luồng dữ liệu chung trong dạng ứng dụng có nhiều game con. Framework đưa ra 2 khái niệm về Private Data Flow và Global Data Flow

  • Private Data Flow : Dòng dữ liệu riêng biệt dành cho các nhóm, minigame độc lập hoặc luồng bên trong một prefab muốn chạy code độc lập.
  • Global Data Flow: Dòng dữ liệu chung cho toàn bộ các X9 Component, X9 Command, ngay từ khi tạo mới khi chưa nằm trong một Private Data Flow nào cả.

Các dòng dữ liệu được tạo ra dựa vào sự kết hợp Dispatcher với Node Tree của Cocos Creator. Với Private Data Flow, quản lý luồng sẽ qua chung một instance Dispatcher. Instance này sẽ được tham chiếu vào node chứa một X9 Component được config là một Facade (xem Facade Component).

Với Global Data Flow, instance của Dispatcher sẽ ở dạng static và là duy nhất toàn bộ game. Dispatcher của Global Data Flow không phụ thuộc vào bất kì node nào.

Facade Component

Facade Component là một X9 Component được thiết lập khả năng tự tạo ra một Private Data Flow cho node sở hữu nó. Thường X9 Component này sẽ được tạo ra như một Scene Component.

Register to Data Flows

Các X9 Component và X9 Command được đăng ký vào “luồng dữ liệu” bằng 2 cách: Kéo thả vào node trên giao diện của Cocos Creator. Được gọi qua hàm use(..) trong môt X9 component đã được đăng ký.

Các thành phần không được đăng ký, mặc định sẽ không có khả năng nhận được dữ liệu trong luồng dữ liệu.

Nếu hàm use(...) được sử dụng trong một component đã đăng ký, đồng thời cũng đã có sẵn component đó trên cùng node của component. Hệ thống sẽ tự động gọi ra tham chiếu tới component đã được tạo sẵn trả về qua hàm use(...). Lưu ý: trong trường hợp có 2 component cùng Class được đặt trên cùng một node. hàm use sẽ chỉ tham chiếu được tới duy nhất tới 01 component.

Component 's Data Priority

Khi một X9 Component B được đăng ký (sử dụng hàm use(...) ) trong script của một X9 Component A, thì dữ liệu của component B sẽ được ưu tiên cập nhật trước khi dữ liệu đến với component A. Khi đó, A hoàn toàn có thể truy xuất lấy dữ liệu mới nhất từ B để hoàn thiện dữ liệu của A. Nếu có B, C, D, E được đăng ký cùng lúc trong A, thì thứ tự cập nhật dữ liệu của B,C,D,E sẽ theo thứ tự khai báo sử dụng hàm use(B), use(C), use(D), use(E). Trường hợp, trong C tiếp tục sử dụng use(D), use(E) thứ tự cập nhật mới sẽ là: B, D, E, C.

Auto Matching Data Flows

Các X9 Component, X9 Command được kéo thả vào node sẽ tự động tìm kiếm ngược dòng lên phía root node trong Node Tree, để đăng ký vào luồng Private Data Flow gần nhất. Nếu không tìm thấy Private Data Flow nào, X9 Component sẽ tự động được gắn vào Global Data Flow.

Component’s State Data

Mỗi X9 Component được thiết kế theo hướng Statement. Có nghĩa là mỗi X9 Component đều có một dạng dữ liệu lưu trữ dưới dạng các key-vaue liên quan đến việc điều khiển hiển thị. Gọi là State Data.

Save And Share Data

Save And Share là Feature Plugin (xem Feature Plugin) có nhiệm vụ lưu trữ và chia sẻ State Data hoặc Data bất kỳ với các Component khác. Với phương thức ‘share’ các State Data được lưu vào qua một “persist root node” (khái niệm trong cocos creator) theo địa chỉ của tương ứng với component đó. Với phương thức ‘save’, State Data được lưu vào localStorage tại địa chỉ lưu của component đó. Khi getData từ Save and Share, hệ thống sẽ lấy data từ vùng share trước, nếu không có sẽ lấy từ vùng save. Tính năng này đảm bảo hai X9 Component ở hai scene khác nhau sẽ có chung dữ liệu lưu trữ và không bị xóa khi scene bị xóa. Ngoài ra, có thể nhận data từ toàn bộ các X9 Component là super class của các Component này (tính năng này là option)

Auto Synchronize State Data

Các component cùng loại (cùng class) sẽ tự động đồng bộ State Data từ “persist root node” hoặc từ localstorage. (Tính năng cùng trong Save And Share Feature Plugin ) Vấn đề này giải quyết bài toàn đồng bộ dữ liệu của x9 component khi chuyển scene - là lúc x9 component được khởi tạo mới từ đầu.

Component ‘s Incoming Data Flows Handler (Core Architect)

Khi một Command được gửi tới Store (đại diện là ReduceStore) sẽ có các khâu cho phép developer can thiệp để tùy chỉnh trạng thái của component như sau:

  • reduce: handler mọi command phát ra từ Dispatcher. Developer sẽ override reduce để quyết định command nào sẽ đi tiếp làm thay đổi trạng thái component bằng cách tạo ra một State Data mới return sang các khâu tiếp theo.
  • areEqual: so sánh State Data cũ với State Data được trả về từ reduce. Nếu trùng nhau trả về true (không đi tiếp), khác nhau trả về false (có sự thay đổi cần đi tiếp để cập nhật trạng thái mới). Developer sẽ overrdie areEqual để quyết định phương pháp so sách các State Data tùy biến theo ý đồ. Mặc định là so sánh tham chiếu thông thường giữa hai Object trong JS.
  • onChange: sau khi xác định có sự thay đổi, khâu này sẽ được gọi cuối cùng để thực thi cập nhật các thay đổi vào giao diện hoặc vào dũ liệu. Developer override onChange để thực hiện các cập nhật từ State Data sang các Data dạng khác hoặc trực tiếp vào giao diện. Các khâu handler này khi sang X9 Framework sẽ được tùy biến tùy theo nhu cầu vận hành của từng ứng dụng. Mỗi sự tùy biến này gọi là các Coding Style Feature.

Coding Style (Advanced Feature)

Trên nền của Component ‘s Incoming Data Flows Handler, để phù hợp với thói quen của từng Developer, X9 Project Framework cho phép code thêm các Class dạng Coding Style hỗ trợ các function tương ứng với thói quen sử dụng của Developer. Coding Style Class can thiệp trực tiếp tới Incoming Data Flows Handler tạo ra hoặc chỉnh sửa thành cách hiểu về luồng mới trên nền của luồng cũ. Các function có thể ghi đè toàn bộ hoặc một phần các function từ bộ Core. Luồng mặc định của X9 Framework là sử dụng Auto Reduce Coding Style. Khai báo sử dụng bằng thuộc tính mixins của cc.Class.

Feature Plugins

Feature Plugins là các Class định nghĩa bổ sung thêm khả năng cho các X9 Component. Các function bổ sung không ảnh hưởng tới Incoming Data Flows Handler của Core chính. Ví dụ: Tính năng Save and Share State Data. Khai báo sử dụng bằng thuộc tính mixins của cc.Class.

## X9 Component và X9 Command

Bản chất X9 Component và X9 Command được tạo ra từ việc kế thừa một cc.Component. X9 Component bổ sung thêm các đoạn code thực hiện các yêu cầu nghiệp vụ của các tính năng bên trên:

  • Tự động phân luồng component trong Auto Matching Data Flows.
  • Tham chiếu hoặc tạo mới component gắn vào data flows trong Register to Data Flows.
  • Tự động sắp xếp thứ tự ưu tiên cập nhật dữ liệu Component 's Data Priority.
  • X9 Command sử dụng nguyên trạng tính năng Command từ Core tuy nhiên bổ sung thêm khả năng có thể tương tác với Multi Data Flows. Cụ thể ở đây là 1 hoặc cả 2 luồng : Private Data FlowGlobal Data Flow. Cụ thể là tính năng quản lý nhiều instance của Dispatcher.

Create new component styles by mix-in feature entities

X9 Project Framework hỗ trợ khả tạo ra các Component dạng mới hỗ trợ nhiều khả năng hơn bằng cách tích hợp các Coding Style, Feature Plugins trong thuộc tính mixin của cc.Class. Ví dụ: X9 Component là cc.Component có thêm: Chức năng ReduceStore trong Core. Coding Style (mặc định là Auto Reduce với cú pháp gửi cmd this.cmd(...) tiện dụng) Save And Share Data lưu và chia sẻ dữ liệu của component với các component khác hoặc chính nó nhưng khác scene.

Khai báo code:

var X9Component= cc.Class({ extends: cc.Component, mixins: [ReduceStore, CodingStyle, SaveAndShareData],.......})

Auto Reduce Coding Style

Một dạng Coding Style, hỗ trợ viết default hàm reduce để phân loại các data flow gửi tới Component (đại diện là Class X9AutoReduceStyle). Các component sử dụng Auto Reduce Style sẽ được hỗ trợ các tính năng sau:

  • Hỗ trợ viết lại hàm reduce phân loại các data flow. Chỉ cần khai báo danh sách các data theo danh sách các nhãn của các data khai báo trong allowCommandTypes().

  • Hỗ trợ hàm cmd(...) cho cả Command lẫn Component. Sử dụng cmd trong component sẽ ko cần tạo mới Command Class để dispatch data vào dispatcher. Cho phép dán nhãn và đánh địa chỉ data gửi đi.

  • Hỗ trợ phân tách luồng Cập nhật trạng thái state data (onUpdateState) và Cập nhật trạng thái hiển thi (onUpdateView) độc lập. Luôn theo thứ tự, cập nhật state data trước sau đó với đến cập nhật view.

  • Hỗ trợ asynchronous cập nhật view của các x9 component tùy biến theo dữ liệu gửi đến (hàm sequence(...)). Xử lý trường hợp chuyển động lần lượt của các X9 Component.

  • Hỗ trợ gửi tập trung các trạng thái hiển thi trong onUpdateView(), sẽ dễ dàng quản lý và tăng tính chịu lỗi cao.

Auto Reduce Coding Style with Incoming Data Flows Handler.

Khi một Command được gửi tới X9 Component (với Auto Reduce Coding Style), data flow sẽ chạy theo thứ tự các bước xử lý: Kiểm tra xem nhãn của data có phải nhãn được cho phép cập nhật vào x9 Component hay không. Liệt kê trong hàm allowCommandTypes(). Cập nhật State Data. Khi toàn bộ các X9 Component được cập nhật State Hoàn tất. Thực thi các async Task cập nhật view của các component trên theo thứ tự tùy biến với nhãn data tương ứng. Phân loại Private Command và Public Command. Quyết định có cập nhật vào View hay không ?. Tại thời điểm này, State Data mới đã được cập nhật. Kết thúc một chu kỳ xử lý Incoming Data Flows.

## Cấu trúc folder mặc định (thư mục assets)

resource

  • common
    • font
    • audio
    • [component]
      • *.png
    • *.prefab
  • [mini_game]
    • font
    • audio
    • [component]
      • *.png
    • *.prefab

scene

  • [project_name]
    • HomeScene.fire
  • welcome.fire

scripts

  • app

    • setting.js
  • [project_name]

    • HomeScene.js
  • welcome

    • WelcomeScene.js
  • module

    • ui
    • [component]
    • [feature_module]
    • [mini_game_module]

Ý tưởng chung của project folder mặc định là hướng vào component và module. Về mặt ‘triết học’ còn đảm bảo tính chung, tính riêng và kế thừa. Ví dụ: Trong thư mục resources: common là thư mục được coi là module chung, Chứa các thư mục component với các asset default sẽ được dùng lại trong toàn bộ ứng dụng và kể cả các mini game.

[mini_game] các thư mục đồng cấp với common thường là thư mục của các minigame hoặc ứng dụng nhỏ bên trong app. Chúng chứa các component riêng với các asset chỉ sử dụng riêng cho component của minigame đó. Trong các script và prefab, có thể được kế thừa, sử dụng lại assets từ các component trong thư mục common và ở các thư mục component khác cùng cấp. Việc phân rõ ràng theo hướng component và module sẽ đảm bảo thuận tiện cho việc tối ưu assets khi sử dụng load bundler của cocos creator. Tránh phình to dự án sau mỗi lần bổ sung tính năng và thay giao diện game.