Cocos Creator:基于JSB桥的事件机械主义

推荐:将NSDT场景编辑器加入你的3D工具链
3D工具集:NSDT简石数字孪生

基于JSB桥的事件机械主义

注意:在 v3.6.0 之后,模块即将弃用,API 会移到命名空间的模块中。jsbnativecc

基于JsbBridge的事件化系统

JsbBridgeWrapper是一个基于,更方便、更易于使用的事件化系统。开发人员可以触发多个事件,而无需手动实现一个事件。但它不是mthread安全的。如果您正在处理复杂的情况,仍然建议自己实现 eventify 系统。JsbBridge

Jsb桥包装器接口介绍

/**
 * Listener for jsbBridgeWrapper's event.
 * It takes one argument as string which is transferred by jsbBridge.
 */
export type OnNativeEventListener = (arg: string) => void;
export namespace jsbBridgeWrapper {
    /** If there's no event registered, the wrapper will create one  */
    export function addNativeEventListener(eventName: string, listener: OnNativeEventListener);
    /**
     * Dispatch the event registered on Objective-C, Java etc.
     * No return value in JS to tell you if it works.
     */
    export function dispatchEventToNative(eventName: string, arg?: string);
    /**
     * Remove all listeners relative.
     */
    export function removeAllListenersForEvent(eventName: string);
    /**
     * Remove the listener specified
     */
    export function removeNativeEventListener(eventName: string, listener: OnNativeEventListener);
    /**
     * Remove all events, use it carefully!
     */
    export function removeAllListeners();
}

OnNativeEventListener是在此处注册的回调类型,但您也可以使用匿名函数进行编码,例如:

import { native } from 'cc'
// When event ‘A’ is triggered, the function ‘this.A’ will be applied
native.jsbBridgeWrapper.addNativeEventListener("A", (usr: string) => {
    this.A(usr);
});

平台实现

JsbBridgeWrapper在不同的平台上有不同的实现。

至于Objective-C和Java,你会看到类似的声明。JsbBridgeWrapper

目标-C:

  // In Objective-C
  typedef void (^OnScriptEventListener)(NSString*);

  @interface JsbBridgeWrapper : NSObject
  /**
   * Get the instance of JsbBridgetWrapper
   */
  + (instancetype)sharedInstance;
  /**
   * Add a listener to specified event, if the event does not exist, the wrapper will create one. Concurrent listener will be ignored
   */
  - (void)addScriptEventListener:(NSString*)eventName listener:(OnScriptEventListener)listener;
  /**
   * Remove listener for specified event, concurrent event will be deleted. Return false only if the event does not exist
   */
  - (bool)removeScriptEventListener:(NSString*)eventName listener:(OnScriptEventListener)listener;
  /**
   * Remove all listener for event specified.
   */
  - (void)removeAllListenersForEvent:(NSString*)eventName;
  /**
   * Remove all event registered. Use it carefully!
   */
  - (void)removeAllListeners;
  /**
   * Dispatch the event with argument, the event should be registered in javascript, or other script language in future.
   */
  - (void)dispatchEventToScript:(NSString*)eventName arg:(NSString*)arg;
  /**
   * Dispatch the event which is registered in javascript, or other script language in future.
   */
  - (void)dispatchEventToScript:(NSString*)eventName;
  @end

JAVA 或 Huawei HarmonyOS:

  // In JAVA
  public class JsbBridgeWrapper {
      public interface OnScriptEventListener {
          void onScriptEvent(String arg);
      }
      /**
       * Add a listener to specified event, if the event does not exist, the wrapper will create one. Concurrent listener will be ignored
       */
      public void addScriptEventListener(String eventName, OnScriptEventListener listener);
      /**
       * Remove listener for specified event, concurrent event will be deleted. Return false only if the event does not exist
       */
      public boolean removeScriptEventListener(String eventName, OnScriptEventListener listener);
      /**
       * Remove all listener for event specified.
       */
      public void removeAllListenersForEvent(String eventName);
      /**
       * Remove all event registered. Use it carefully!
       */
      public void removeAllListeners() {
          this.eventMap.clear();
      }
      /**
       * Dispatch the event with argument, the event should be registered in javascript, or other script language in future.
       */
      public void dispatchEventToScript(String eventName, String arg);
      /**
       * Dispatch the event which is registered in javascript, or other script language in future.
       */
      public void dispatchEventToScript(String eventName);
  }

基本用法

注册JS事件,并使用Objective-C/JAVA触发JavaScript事件

我们仍然可以满足简单的需求:使用本机回调结果更改标签内容。一旦本机事件被触发,它将指定的文本返回到 JavaScript。在此之前,我们应该为 .changeLabelContent

注册 JS 事件

public changeLabelContent(user: string): void {
    console.log("Hello " + user + " I'm K");
    this.labelForContent!.string = "Hello " + user + " ! I'm K";
}
native.jsbBridgeWrapper.addNativeEventListener("changeLabelContent", (usr: string) => {
        this.changeLabelContent(usr);
});

将事件调度到 JS

触发事件后,标签内容将更改为指定字符串的组成。在此之前,我们应该注册本机事件。changeLabelContent

Objective-C 代码示例:

  // Objective-C
  JsbBridgeWrapper* m = [JsbBridgeWrapper sharedInstance];
  OnScriptEventListener requestLabelContent = ^void(NSString* arg){
      JsbBridgeWrapper* m = [JsbBridgeWrapper sharedInstance];
      [m dispatchEventToScript:@"changeLabelContent" arg:@"Charlotte"];
  };
  [m addScriptEventListener:@"requestLabelContent" listener:requestLabelContent];

JAVA 代码示例:

  // JAVA
  JsbBridgeWrapper jbw = JsbBridgeWrapper.getInstance();
  jbw.addScriptEventListener("requestLabelContent", arg ->{
      System.out.print("@JAVA: here is the argument transport in" + arg);
      jbw.dispatchEventToScript("changeLabelContent","Charlotte");
  });
注意:您也可以在 JAVA 中使用匿名函数。

将事件调度到本机

这里的返回值设置为const值,当Objective-C/JAVA中的JsbBridgeWrapper收到事件通知时,它将触发一个返回值。requestLabelContentchangeLabelContent

最后一步,添加一个按钮来开始我们的测试。代码示例如下:

// Button click event for SAY HELLO
public sayHelloBtn() {
    native.jsbBridgeWrapper.dispatchEventToNative("requestLabelContent");
}

效果与 JsbBridge 的测试用例相同,点击按钮,标签内容将变为欢迎消息。此外,JsbBridge 的示例案例在存储库中更新。SAY HELLO

3D建模学习工作室 翻译整理,转载请注明出处

上一篇:Cocos Creator:使用 JavaScript 调用 Objective-C 方法的更简单方法 (mvrlink.com)

下一篇:Cocos Creator:CMake 使用介绍 (mvrlink.com)

NSDT场景编辑器 | NSDT 数字孪生 | GLTF在线编辑器 | 3D模型在线转换 | UnrealSynth虚幻合成数据生成器 | 3D模型自动纹理化工具
2023 power by nsdt©鄂ICP备2023000829号