MAX/MSP SDK学习04:Messages selector的使用

其实消息选择器在simplemax示例中就接触到了,但这文档非要讲那么抽象。目前为止对消息选择器的理解是:可判断接收过来的消息是否符合本Object的处理要求,比如加法对象只可接收数值型的消息以处理,但不能接收t_symbol型的消息,如下:


1. Messages selector

如下面自定义的myObjectABC可从出口发送消息选择器为 "ABC" 的消息,myObjectInt可发送消息选择器为 "int" 的消息。MAX/MSP SDK学习03:Atoms and Messages的使用中的IsMatchABC组件可接收处理 "ABC" 消息和 "int" 消息。

myObjectABC:

#include "ext.h"					// standard Max include, always required
#include "ext_obex.h"				// required for new style Max object

typedef struct _myObjectABC {
	t_object ob;     // the object itself (must be first)
	void* outLet;    // 出口
} t_myObjectABC;

// function prototypes
void* myObjectABC_new(t_symbol* s, long argc, t_atom* argv);
void myObjectABC_free(t_myObjectABC* x);
void myObjectABC_assist(t_myObjectABC* x, void* b, long m, long a, char* s);
void myObjectABC_bang(t_myObjectABC* x);

// global class pointer variable
void* myObjectABC_class;

void ext_main(void* r) {
	t_class* c;

	// "myObjectABC" 建议和项目名一样,否则在max/msp中创建自定义组件会出问题
	c = class_new("myObjectABC", (method)myObjectABC_new, (method)myObjectABC_free, (long)sizeof(t_myObjectABC),
		0L /* leave NULL!! */, A_GIMME, 0);

	/* you CAN'T call this from the patcher */
	// Object将接收到的消息(int、bang、assist等)与消息选择器中的对比,比对成功则可调用相关C方法,否则"Object dosen't understand message"
	// A_CANT、A_LONG等指定typed方法,A_GIMME:a list of atoms,适用于超过四个参数或者多个浮点数
	class_addmethod(c, (method)myObjectABC_assist, "assist", A_CANT, 0);
	class_addmethod(c, (method)myObjectABC_bang, "bang", 0);

	class_register(CLASS_BOX, c); /* CLASS_NOBOX */
	myObjectABC_class = c;

	post("I am the myObjectABC object");
}

void myObjectABC_assist(t_myObjectABC* x, void* b, long m, long a, char* s) {
	if (m == ASSIST_INLET) { // inlet
		sprintf(s, "I am inlet %ld", a);
	} else {	// outlet
		sprintf(s, "I am outlet %ld", a);
	}
}

void myObjectABC_free(t_myObjectABC* x) {
	;
}

/* argc指在创建组件时,直接跟在组件后面的参数个数;argv存储参数具体值*/
void* myObjectABC_new(t_symbol* s, long argc, t_atom* argv) {  // 分配内存创建object,初始化属性,创建入口和出口(默认一个入口,无出口)
	t_myObjectABC* x = NULL;
	long i;

	if ((x = (t_myObjectABC*)object_alloc(myObjectABC_class))) {  // 使用全局指针创建新实例
		object_post((t_object*)x, "a new %s object was instantiated: %p", s->s_name, x);
		object_post((t_object*)x, "it has %ld arguments", argc);
		x->outLet = outlet_new((t_object*)x, NULL);
	}
	return (x);
}

void myObjectABC_bang(t_myObjectABC* x) {
	t_atom argv[3];   // t_atom类型可存储整型、浮点型、t_symbol类型、指针。
	atom_setlong(argv, 666);
	atom_setsym(argv + 1, gensym("MYM"));  // 字符串需要用gensym转换成t_symbol* 类型
	atom_setfloat(argv + 2, 0.123);
	outlet_anything(x->outLet, gensym("ABC"), 3, argv);
}

myObjectInt:

#include "ext.h"					// standard Max include, always required
#include "ext_obex.h"				// required for new style Max object

typedef struct _myObjectInt {
	t_object ob;     // the object itself (must be first)
	void* outLet;    // 出口
} t_myObjectInt;

// function prototypes
void* myObjectInt_new(t_symbol* s, long argc, t_atom* argv);
void myObjectInt_free(t_myObjectInt* x);
void myObjectInt_assist(t_myObjectInt* x, void* b, long m, long a, char* s);
void myObjectInt_bang(t_myObjectInt* x);

// global class pointer variable
void* myObjectInt_class;

void ext_main(void* r) {
	t_class* c;

	// "myObjectInt" 建议和项目名一样,否则在max/msp中创建自定义组件会出问题
	c = class_new("myObjectInt", (method)myObjectInt_new, (method)myObjectInt_free, (long)sizeof(t_myObjectInt),
		0L /* leave NULL!! */, A_GIMME, 0);

	/* you CAN'T call this from the patcher */
	// Object将接收到的消息(int、bang、assist等)与消息选择器中的对比,比对成功则可调用相关C方法,否则"Object dosen't understand message"
	// A_CANT、A_LONG等指定typed方法,A_GIMME:a list of atoms,适用于超过四个参数或者多个浮点数
	class_addmethod(c, (method)myObjectInt_assist, "assist", A_CANT, 0);
	class_addmethod(c, (method)myObjectInt_bang, "bang", 0);

	class_register(CLASS_BOX, c); /* CLASS_NOBOX */
	myObjectInt_class = c;

	post("I am the myObjectInt object");
}

void myObjectInt_assist(t_myObjectInt* x, void* b, long m, long a, char* s) {
	if (m == ASSIST_INLET) { // inlet
		sprintf(s, "I am inlet %ld", a);
	} else {	// outlet
		sprintf(s, "I am outlet %ld", a);
	}
}

void myObjectInt_free(t_myObjectInt* x) {
	;
}

/* argc指在创建组件时,直接跟在组件后面的参数个数;argv存储参数具体值*/
void* myObjectInt_new(t_symbol* s, long argc, t_atom* argv) {  // 分配内存创建object,初始化属性,创建入口和出口(默认一个入口,无出口)
	t_myObjectInt* x = NULL;
	long i;

	if ((x = (t_myObjectInt*)object_alloc(myObjectInt_class))) {  // 使用全局指针创建新实例
		object_post((t_object*)x, "a new %s object was instantiated: %p", s->s_name, x);
		object_post((t_object*)x, "it has %ld arguments", argc);
		x->outLet = outlet_new((t_object*)x, NULL);
	}
	return (x);
}

void myObjectInt_bang(t_myObjectInt* x) {
	t_atom argv[3];   // t_atom类型可存储整型、浮点型、t_symbol类型、指针。
	atom_setlong(argv, 666);
	atom_setsym(argv + 1, gensym("MYM"));  // 字符串需要用gensym转换成t_symbol* 类型
	atom_setfloat(argv + 2, 0.123);
	outlet_anything(x->outLet, gensym("int"), 3, argv);
}

将myObjectABC和myObjectInt的出口都接入IsMatchABC的左入口,测试消息选择器的使用。

运行结果:

         


2. anything method

若某t_symbol消息匹配不到消息选择器,则可定义通用处理方法anything method,如下:

#include "ext.h"			// standard Max include, always required
#include "ext_obex.h"		// required for new style Max object

typedef struct _anything {
	t_object	ob;			// the object itself (must be first)
} t_anything;

void* anything_new(t_symbol* s, long argc, t_atom* argv);
void anything_free(t_anything* x);
void anything_assist(t_anything* x, void* b, long m, long a, char* s);

void anything_anything(t_anything* x, t_symbol* s, long argc, t_atom* argv);

void* anything_class;

void ext_main(void* r) {
	t_class* c;

	// "anything" 建议和项目名一样,否则在max/msp中创建自定义组件会出问题
	c = class_new("anything", (method)anything_new, (method)anything_free, (long)sizeof(t_anything),
		0L /* leave NULL!! */, A_GIMME, 0);

	class_addmethod(c, (method)anything_assist, "assist", A_CANT, 0);
	class_addmethod(c, (method)anything_anything, "anything", A_GIMME, 0);

	class_register(CLASS_BOX, c); /* CLASS_NOBOX */
	anything_class = c;

	post("I am the anything object");
}

void anything_assist(t_anything* x, void* b, long m, long a, char* s) {
	if (m == ASSIST_INLET) { // inlet
		sprintf(s, "I am inlet %ld", a);
	} else {	// outlet
		sprintf(s, "I am outlet %ld", a);
	}
}

void anything_free(t_anything* x) {
	;
}

/* argc指在创建组件时,直接跟在组件后面的参数个数;argv存储参数具体值*/
void* anything_new(t_symbol* s, long argc, t_atom* argv) {  // 分配内存创建object,初始化属性,创建入口和出口(默认一个入口,无出口)
	t_anything* x = NULL;
	x = (t_anything*)object_alloc(anything_class);
	return (x);
}

void anything_anything(t_anything* x, t_symbol* s, long argc, t_atom* argv) {
	object_post((t_object*)x, "Invoked by [%s] message", s->s_name);
}

运行结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/177925.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【华为OD题库-032】数字游戏-java

题目 小明玩一个游戏。系统发1n张牌,每张牌上有一个整数。第一张给小明,后n张按照发牌顺序排成连续的一行。需要小明判断,后n张牌中,是否存在连续的若干张牌,其和可以整除小明手中牌上的数字. 输入描述: 输入数据有多组…

DB2—03(DB2中常见基础操作)

DB2—03(DB2中常见基础操作) 1. 前言1.1 oracle和mysql相关 2. db2中的"dual"2.1 SYSIBM.SYSDUMMY12.2 使用VALUES2.3 SYSIBM.SYSDUMMY1 "变" dual 3. db2中常用函数3.1 nvl()、value()、COALESCE()3.2 NULLIF() 函数3.3 LISTAGG() …

成为AI产品经理——AI产品经理工作全流程

一、业务背景 背景:日常排球训练,中考排球项目和排球体测项目耗费大量人力成本和时间成本。 目标:开发一套用于实时检测排球运动并进行排球垫球计数和姿势分析的软件。 二、产品工作流程 我们这里对于产品工作流程的关键部分进行讲解&…

SQL 中的 MIN 和 MAX 以及常见函数详解及示例演示

SQL MIN() 和 MAX() 函数 SQL中的MIN()函数和MAX()函数用于查找所选列的最小值和最大值,分别。以下是它们的用法和示例: MIN() 函数 MIN()函数返回所选列的最小值。 示例: 查找Products表中的最低价格: SELECT MIN(Price) F…

Vue 重写push和replace方法,解决:Avoided redundant navigation to current location

当我们使用编程式路由导航跳转路径时,如果我们两次携带同样的参数进行跳转,会进行页面报错: 那产生这个问题的原因是什么呢? 我们接收并输出调用push方法返回的结果: 会发现这是一个Promise对象 我们都知道&#xff…

2023年G2电站锅炉司炉证考试题库及G2电站锅炉司炉试题解析

题库来源:安全生产模拟考试一点通公众号小程序 2023年G2电站锅炉司炉证考试题库及G2电站锅炉司炉试题解析是安全生产模拟考试一点通结合(安监局)特种作业人员操作证考试大纲和(质检局)特种设备作业人员上岗证考试大纲…

【Java 进阶篇】Redis 数据结构:轻松驾驭多样性

引言 Redis是一款强大的键值对存储系统,其数据结构的多样性是其引以为傲的特点之一。在这篇博客中,我们将深入探讨Redis的主要数据结构,包括字符串、哈希表、列表、集合和有序集合,并通过实例代码演示它们的用法。 1. 字符串&am…

小程序存在优惠卷遍历,但是歪了

进入小程序,因为是一个小商城,所以照例先查看收货地址是否存在越权,以及能否未授权访问,但是发现不存在这些问题,所以去查看优惠卷 进入领券中心,点击领取优惠券时抓包 发现数据包,存在敏感参数…

基于SpringBoot+Vue的体检预约管理系统

基于SpringBootVue的体检预约管理系统的设计与实现~ 开发语言:Java数据库:MySQL技术:SpringBootMyBatisVue工具:IDEA/Ecilpse、Navicat、Maven 系统展示 主页 管理员界面 用户界面 摘要 体检预约管理系统是一种基于Spring Boot…

Node.js入门指南(一)

目录 Node.js入门 什么是Node.js Node.js的作用 Node.js安装 Node.js编码注意事项 Buffer(缓冲器) 定义 使用 fs模块 概念 文件写入 文件读取 文件移动与重命名 文件删除 文件夹操作 查看资源状态 路径问题 path模块 Node.js入门 什么是Node.js …

SSH连接远程服务器报错:WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED 解决方法

一.错误描述 报错信息里提示了路径信息/root/.ssh/known_hosts:20 二.解决方案 方法一 输入以下指令: ssh-keygen -R XXX(需要连接远程服务器的ip) 按照我的例子ip:10.165.7.136,会返回以下信息: 重新尝试连接: 输…

数据结构学习笔记——多维数组、矩阵与广义表

目录 一、多维数组(一)数组的定义(二)二维数组(三)多维数组的存储(四)多维数组的下标的相关计算 二、矩阵(一)特殊矩阵和稀疏矩阵(二)…

7种SQL的进阶用法

1.自定义排序(ORDER BY FIELD) 在MySQL中ORDER BY排序除了可以用ASC和DESC之外,还可以使用自定义排序方式来实现。 CREATE TABLE movies ( id INT PRIMARY KEY AUTO_INCREMENT, movie_name VARCHAR(255), actors VARCHAR(255), price DEC…

MySQL面试,MySQL事务,MySQL锁,MySQL集群,主从,MySQL分区,分表,InnoDB

文章目录 数据库-MySQLMySQL主从、集群模式简单介绍1、主从模式 Replication2、集群模式3、主从模式部署注意事项 UNION 和 UNION ALL 区别分库分表1.垂直拆分2、水平拆分 MySQL有哪些数据类型1、整数类型**,2、实数类型**,3、字符串类型**,4…

MySQL 事务的底层原理和 MVCC(一)

在事务的实现机制上,MySQL 采用的是 WAL(Write-ahead logging,预写式日志)机制来实现的。 在使用 WAL 的系统中,所有的修改都先被写入到日志中,然后再被应用到系统中。通常包含 redo 和 undo 两部分信息。 …

初识Java 18-2 泛型

目录 构建复杂模型 类型擦除 C中的泛型 迁移的兼容性 类型擦除存在的问题 边界的行为 对类型擦除的补偿 创建类型实例 泛型数组 本笔记参考自: 《On Java 中文版》 构建复杂模型 泛型的一个优点就是,能够简单且安全地创建复杂模型。 【例子&am…

广告机/商业显示屏_基于MT878安卓主板方案

安卓主板在广告机领域扮演着重要的角色。无论是在商场、车站、酒店、电梯、机场还是高铁站,LED广告机广泛应用,并通过不同方式进行播放和管理。 广告机/商业显示屏_基于MT878安卓主板方案 基于MT8788安卓主板方案的广告机采用了联发科MT8788八核芯片方案…

力扣.面试题 04.06. 后继者(java 树的中序遍历)

Problem: 面试题 04.06. 后继者 文章目录 题目描述思路解题方法复杂度Code 题目描述 设计一个算法,找出二叉搜索树中指定节点的“下一个”节点(也即中序后继)。 如果指定节点没有对应的“下一个”节点,则返回null。 思路 由于题…

msvcp140.dll是什么?msvcp140.dll丢失的有哪些解决方法

在计算机使用过程中,我们经常会遇到一些错误提示,其中之一就是“msvcp140.dll丢失”。这个错误通常会导致某些应用程序无法正常运行。为了解决这个问题,我们需要采取一些措施来修复丢失的msvcp140.dll文件。本文将详细介绍5个解决msvcp140.dl…

visual studio 如何建立 C 语言项目

安装这个 模块。 新建 空项目 创建完成 写demo 点击运行: