Detailed explanation of CocosCreator message distribution mechanism

Detailed explanation of CocosCreator message distribution mechanism

Overview

This article begins to introduce content related to game business architecture. At the game business layer, all systems that need to be isolated and communications between modules can be decoupled through message distribution. For example, network return notifications, data updates synchronized to the interface, etc.

Message distribution is designed based on the observer pattern. The place where the message needs to be processed registers the listening callback with the message center. When the message is dispatched, the dispatch interface of the message center is called to traverse the listening queue of the message and call the corresponding callback method.

Specific plan

First define the listening callback type

/**
 * Message monitoring callback method */
export type NotifyListener = (src: any, data: any) => void;

Save the listening queue by key-value

private static msg2listDict: Dictionary< string, Array<NotifyListenerInfo> > = new Dictionary< string, Array<NotifyListenerInfo> >();

Interface Definition

/**
 * Add multiple listeners, need to remove manually * @param msg
 * @param listener
 * @param target
 */
public static addListener(msg: string, listener: NotifyListener, target?: any): void {}
 
/**
 * Add a one-time listener and remove it after the event is triggered* @param msg
 * @param listener
 * @param target
 */
public static addOnceListener(msg: string, listener: NotifyListener, target?: any): void {}
 
/**
 * Remove the listener specified by the specified message * @param msg
 * @param listener
 */
public static removeMsgListener(msg: string, listener: NotifyListener): void {}
 
/**
 * Remove all listeners of the specified message * @param msg
 */
public static removeMsgAllListeners(msg: string): void {}
 
/**
 * Remove the specified target's monitoring of the specified message * @param msg
 * @param target
 */
public static removeTargetMsgListen(msg: string, target: any): void {}
 
/**
 * Remove all message listeners of the specified target * @param target
 */
public static removeTargetAllMsgListen(target: any): void {}
 
/**
 * Send message * @param msg
 * @param src
 * @param data
 */
public static notify(msg: string, src: any, data: any): void {}

In the add and remove implementation, you need to be aware that a message may be being dispatched.

For a newly added listener of a message, it should be distributed after the current queue message is distributed. Therefore, add a queue to be added

private static listener2add: Array<NotifyListenerInfo> = [];

Make the following judgment when adding a listener

// The message is being dispatched and put into the queue to be added if (NotifyCenter.notifyMsgs.indexOf(msg) >= 0) {
    NotifyCenter.listener2add.push(info);
    return;
}

Similarly, when removing the listener, the message may be dispatched. To avoid the modification of the queue causing the for loop exception, add a queue to be removed. When dispatching the message, if the listener is in the removal queue, it will not be dispatched. After the message is dispatched, remove it from the queue

private static listener2remove: Array<NotifyListenerInfo> = [];

Make the following judgment when removing the listener

// The message is being dispatched and put into the queue to be removed if (NotifyCenter.notifyMsgs.indexOf(msg) >= 0) {
    NotifyCenter.listener2remove.push(list[i]);
} else {
    list.splice(i, 1);
}

When dispatching a message, iterate through the queues under the specified message

// The queue does not exist, no need to process let list = NotifyCenter.msg2listDict.get(msg);
if (!list) {
    return;
}
 
// Mark the message as being dispatched. Multiple messages may be dispatched at the same time. The same message may be marked multiple times. NotifyCenter.notifyMsgs.push(msg);
 
// Process message dispatch for (let i = 0, n = list.length; i < n; i++) {
    NotifyCenter._dispatch(list[i], src, data, false);
}

When dispatching a message, first determine whether the queue is being removed

// In the removal queue, no dispatch if (NotifyCenter.listener2remove.indexOf(info) >= 0) {
    return;
}

After the current queue is dispatched, check the queue to be added

// Process the queue to be added for (let i = 0, n = msg2add.length; i < n; i++) {
    if (listener2add[i].msg == msg) {
        NotifyCenter._dispatch(listener2add[i], src, data, true);
    }
}

A message distribution center is introduced to allow isolated systems and modules to communicate through message monitoring and dispatching to avoid mutual reference coupling.

The above is a detailed explanation of the CocosCreator message distribution mechanism. For more information about CocosCreator message distribution, please pay attention to other related articles on 123WORDPRESS.COM!

You may also be interested in:
  • How to use JSZip in vue.js to decompress files on the front end
  • Interpretation of CocosCreator source code: engine startup and main loop
  • CocosCreator general framework design resource management
  • How to make a List in CocosCreator
  • Analysis of CocosCreator's new resource management system
  • CocosCreator Skeleton Animation Dragon Bones
  • How to draw a cool radar chart in CocosCreator
  • Detailed explanation of CocosCreator MVC architecture
  • How to use JSZip compression in CocosCreator

<<:  Detailed explanation of the order of Mysql query results according to the order of ID in in()

>>:  The best way to start a jar package project under Centos7 server

Recommend

Solve the compatibility issue between MySQL 8.0 driver and Alibaba Druid version

This article mainly introduces the solution to th...

Detailed explanation of the cache implementation principle of Vue computed

Table of contents Initialize computed Dependency ...

Automatic file synchronization between two Linux servers

When server B (172.17.166.11) is powered on or re...

Nodejs combined with Socket.IO to realize websocket instant communication

Table of contents Why use websocket Socket.io Ope...

A brief analysis of the basic implementation of Vue detection data changes

Table of contents 1. Object change detection 2. Q...

Docker Nginx container production and deployment implementation method

Quick Start 1. Find the nginx image on Docker Hub...

Analysis of CocosCreator's new resource management system

Table of contents 1. Resources and Construction 1...

Detailed explanation of MySQL phantom reads and how to eliminate them

Table of contents Transaction Isolation Level Wha...

How to deploy gitlab using Docker-compose

Docker-compose deploys gitlab 1. Install Docker I...

Tutorial diagram of installing mysql8.0.18 under linux (Centos7)

1 Get the installation resource package mysql-8.0...

A quick solution to the problem of PC and mobile adaptation

When making a web page, we usually need to consid...

CSS Transition expands and collapses elements by changing the Height

A common development need is that we want to coll...

Small program to implement a simple calculator

This article example shares the specific code of ...