Skip to main content

f8-features-event-workflow

Use when implementing or troubleshooting Event feature workflows — message dispatching, event listening, EventDispatcher auto-cleanup, and strongly typed zero-GC event parameters (0-7 args, no object[] compatibility path) in F8Framework.

소스 정보

저장소
TippingGame/F8Framework
최근 소스 활동
2026년 4월 9일 16:14
감지된 SKILL.md 언어
영어
스타
886
포크
141

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

파일 탐색기
2 개 파일

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
f8-features-event-workflow
description
Use when implementing or troubleshooting Event feature workflows — message dispatching, event listening, EventDispatcher auto-cleanup, and strongly typed zero-GC event parameters (0-7 args, no object[] compatibility path) in F8Framework.
# Event Feature Workflow > **⚠️ IMPORTANT**: Before using this feature, you **MUST** formally initialize F8Framework in the launch sequence. Ensure `ModuleCenter.Initialize(this);` has run first, then create the required module, for example `FF8.Message = ModuleCenter.CreateModule<MessageManager>();`. ## Use this skill when - The task is about event/message dispatching and listening. - The user asks about decoupled communication between components. - The user needs EventDispatcher auto-cleanup on UI or entities. - Troubleshooting event dead loops or missing callbacks. ## Path resolution 1. Prefer project source at Assets/F8Framework. 2. If F8Framework is installed as a package, use Packages/F8Framework. 3. For usage docs, read: Assets/F8Framework/Tests/Event/README.md ## Sources of truth - Runtime module: Assets/F8Framework/Runtime/Event - Editor module: Assets/F8Framework/Editor/Event - Test docs: Assets/F8Framework/Tests/Event ## Key classes and interfaces | Class | Role | |-------|------| | `MessageManager` | Core module. Access via `FF8.Message`. Global event bus. | | `EventDispatcher` | Mixin base class for auto-cleanup event listeners. Used by BaseView. | ## API quick reference ### Define events ```csharp public enum MessageEvent { Empty = 10000, ApplicationFocus = 10001, NotApplicationFocus = 10002, ApplicationQuit = 10003, } ``` ### Global event listening (via FF8.Message) ```csharp // Add listener (supports int and enum, pass 'this' for auto-cleanup) FF8.Message.AddEventListener(MessageEvent.ApplicationFocus, OnEvent, this); FF8.Message.AddEventListener<int, string>(10002, OnEventNoGC, this); FF8.Message.AddEventListener<MessageEvent, int, string>(MessageEvent.ApplicationFocus, OnEventNoGC, this); FF8.Message.AddEventListener<int, string, bool, float, long, byte, char>(10004, OnEventT7, this); // Dispatch event (without/with parameters) FF8.Message.DispatchEvent(MessageEvent.ApplicationFocus); FF8.Message.DispatchEvent(10002, 123, "data"); FF8.Message.DispatchEvent(MessageEvent.ApplicationFocus, 123, "data"); FF8.Message.DispatchEvent(10004, 123, "data", true, 1.5f, 999L, (byte)7, 'F'); // Async frame-sliced dispatch (executes 1 listener per frame) FF8.Message.DispatchEventAsync(MessageEvent.ApplicationFocus); FF8.Message.DispatchEventAsync(10002, 123, "data"); FF8.Message.DispatchEventAsync(MessageEvent.ApplicationFocus, 123, "data"); FF8.Message.DispatchEventAsync(10004, 123, "data", true, 1.5f, 999L, (byte)7, 'F'); // Remove listener FF8.Message.RemoveEventListener(MessageEvent.ApplicationFocus, OnEvent, this); FF8.Message.RemoveEventListener<int, string>(10002, OnEventNoGC, this); FF8.Message.RemoveEventListener<MessageEvent, int, string>(MessageEvent.ApplicationFocus, OnEventNoGC, this); FF8.Message.RemoveEventListener<int, string, bool, float, long, byte, char>(10004, OnEventT7, this); // Callback signatures void OnEvent() { } void OnEventNoGC(int id, string name) { } void OnEventT7(int id, string name, bool active, float speed, long score, byte level, char rank) { } ``` ### EventDispatcher pattern (auto-cleanup) ```csharp // In classes inheriting EventDispatcher (e.g., BaseView): AddEventListener(MessageEvent.ApplicationFocus, OnEvent); AddEventListener<int, string>(10002, OnEventNoGC); AddEventListener<int, string, bool, float, long, byte, char>(10004, OnEventT7); DispatchEvent(MessageEvent.ApplicationFocus); DispatchEvent(10002, 123, "data"); DispatchEvent(10004, 123, "data", true, 1.5f, 999L, (byte)7, 'F'); DispatchEventAsync(MessageEvent.ApplicationFocus); DispatchEventAsync(10002, 123, "data"); DispatchEventAsync(10004, 123, "data", true, 1.5f, 999L, (byte)7, 'F'); RemoveEventListener(MessageEvent.ApplicationFocus, OnEvent); RemoveEventListener<int, string>(10002, OnEventNoGC); RemoveEventListener<int, string, bool, float, long, byte, char>(10004, OnEventT7); // All listeners auto-cleaned on Clear() ``` ### Zero-GC recommendation ```csharp // Use the fixed-parameter overload matching the event payload size. FF8.Message.AddEventListener<int>(10010, OnHpChanged, this); FF8.Message.DispatchEvent(10010, 99); FF8.Message.DispatchEventAsync(10010, 99); FF8.Message.AddEventListener<int, int>(10011, OnDamage, this); FF8.Message.DispatchEvent(10011, 12, 3); FF8.Message.DispatchEventAsync(10011, 12, 3); FF8.Message.AddEventListener<int, int, int, int, int, int, int>(10012, OnCombo, this); FF8.Message.DispatchEvent(10012, 1, 2, 3, 4, 5, 6, 7); FF8.Message.DispatchEventAsync(10012, 1, 2, 3, 4, 5, 6, 7); void OnHpChanged(int hp) { } void OnDamage(int damage, int criticalType) { } void OnCombo(int a, int b, int c, int d, int e, int f, int g) { } ``` ## Workflow 1. Define event IDs as enum (start from 10000 to avoid framework conflicts). 2. Choose pattern: global `FF8.Message` or `EventDispatcher` mixin. 3. For UI/entity classes, prefer `EventDispatcher` for automatic cleanup. 4. Use the strongly typed overload matching the event payload size; the event module now supports 0~7 fixed parameters. 5. If you need to spread callback cost across frames, use `DispatchEventAsync(...)`; the current implementation executes 1 listener per frame. 6. Always pass `this` as the last parameter to `AddEventListener` for lifecycle binding. 7. The framework has built-in dead-loop prevention. 8. Use the Event System Monitor editor window to debug active listeners. ## Common error handling | Error | Cause | Solution | |-------|-------|----------| | Event not received | Listener added after dispatch | Ensure listener registration before dispatch | | Dead loop warning | Event A dispatches Event B which dispatches Event A | Break the cycle, use intermediate state | | Memory leak | Listeners not removed on destroy | Use EventDispatcher or pass `this` for auto-cleanup | | Wrong callback signature | Params mismatch | Match the overload exactly: `void()`, `void(T1)`, `void(T1,T2)` ... `void(T1,T2,T3,T4,T5,T6,T7)` | ## Cross-module dependencies - **UI**: BaseView extends EventDispatcher for auto-cleanup. - **Timer**: Application focus events used by Timer module. ## Output checklist - Event ID enum defined with proper range. - Listener pattern selected (global / EventDispatcher). - Files changed and why. - Validation status and remaining risks.
GitHub에서 보기