Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Unity] 支持拆分C# API 声明文件 #1877

Open
Geequlim opened this issue Oct 23, 2024 · 10 comments
Open

[Unity] 支持拆分C# API 声明文件 #1877

Geequlim opened this issue Oct 23, 2024 · 10 comments

Comments

@Geequlim
Copy link
Contributor

detail | 详细描述

现在将所有 C# API 生成到同一个文件中有如下痛点

  • 声明文件经常由于 Unity 平台、版本的些许差异、每个人使用的插件差异导致生成内容不一致而在版本控制器中频繁冲突
  • 多个平台经常使用不同的宏来接入SDK 决定了生成的不同平台的 C# API 有差异而导致 ts 编译不通过
    • 如在 Android 平台定义的 AndroidUtils 类在切换到 iOS 平台后生成的声明文件中没有它而编译ts项目时用到AndroidUtils的ts代码无法通过编译。
@chexiongsheng
Copy link
Collaborator

提供个样例?一个简单的c# class,怎么提供单独的声明,然后使用方怎么去使用

@Geequlim
Copy link
Contributor Author

@chexiongsheng 如下,为了解决 iOS 平台的类CS.DeadMosquito.IosGoodies 在切换到其他平台后生成的声明缺失,我们将生成的 API 另存为新的声明文件来解决。

ios-goodies.d.ts

declare namespace CS {
	namespace DeadMosquito.IosGoodies {
		class Contact extends System.Object {
			protected [__keep_incompatibility]: never;
			public get Identifier(): string;
			public get NamePrefix(): string;
			public get GivenName(): string;
			public get MiddleName(): string;
			public get FamilyName(): string;
			public get PreviousFamilyName(): string;
			public get NameSuffix(): string;
			public get Nickname(): string;
			public get OrganizationName(): string;
			public get DepartmentName(): string;
			public get JobTitle(): string;
			public get PhoneticGivenName(): string;
			public get PhoneticMiddleName(): string;
			public get PhoneticFamilyName(): string;
			public get PhoneticOrganizationName(): string;
			public get Note(): string;
			public get Birthday(): System.DateTime | null;
			public get PhoneNumbers(): System.Collections.Generic.List$1<DeadMosquito.IosGoodies.ContactPhoneNumber>;
			public get Emails(): System.Collections.Generic.List$1<DeadMosquito.IosGoodies.ContactEmail>;
			public get PostalAddresses(): System.Collections.Generic.List$1<DeadMosquito.IosGoodies.ContactPostalAddress>;
			public get Urls(): System.Collections.Generic.List$1<DeadMosquito.IosGoodies.ContactUrlAddress>;
			public get Relations(): System.Collections.Generic.List$1<DeadMosquito.IosGoodies.ContactRelation>;
			public get SocialProfiles(): System.Collections.Generic.List$1<DeadMosquito.IosGoodies.ContactSocialProfile>;
			public get InstantMessageAddresses(): System.Collections.Generic.List$1<DeadMosquito.IosGoodies.ContactInstantMessageAddress>;
			public get Dates(): System.Collections.Generic.List$1<DeadMosquito.IosGoodies.ContactDate>;
			public static FromJson($jsonString: string): DeadMosquito.IosGoodies.Contact;
			public constructor();
		}
	}
}

@Geequlim
Copy link
Contributor Author

Geequlim commented Oct 28, 2024

最近在梳理各平台SDK接入这块,现在想法已经相对成熟。

提议: 通过为 Typing 注解添加参数,指定生成声明文件的路径

实际使用示例:

通过制作 Unity Package 实现 iOS 相关的功能,包含所有该功能相关的CS/TS代码,link.xml 配置等。在需要的平台中引入此包即可完成集成操作。

通过 Packages/ios-basic/Editor/TypeScriptAPI.cs 定义 Puerts 导出规则

using System;
using System.Collections.Generic;
using Puerts;

namespace tiny.platform.ios {
	[Configure]
	public class TypeScriptAPI {

		static HashSet<string> StaticBindingNamespaces = new HashSet<string>() {};
		static HashSet<string> ReflectionNamespaces = new HashSet<string>() {
			"UnityEngine.iOS",
			"Unity.Advertisement.IosSupport",
		};
		static Dictionary<string, HashSet<string>> IgnoredClasses = new Dictionary<string, HashSet<string>>() {};
		static HashSet<Type> ReflectionTypings = new HashSet<Type>() {};

                // 此处设置返回的类型将声明写入参数传入的文件路径
		[Typing("Packages/ios-basic/ios-support.d.ts")]
		static IEnumerable<Type> Typings {
			get {
				var namespaces = new HashSet<string>(ReflectionNamespaces);
				namespaces.UnionWith(StaticBindingNamespaces);
				var types = PuertsEditorUtils.GetTypes(namespaces, null, IgnoredClasses);
				types.UnionWith(ReflectionTypings);
				return types;
			}
		}
	}
}

@Geequlim Geequlim changed the title [Unity] 声明文件按命名空间生成多个文件 [Unity] 支持拆分C# API 声明文件 Oct 28, 2024
@chexiongsheng
Copy link
Collaborator

没写怎么导入使用。
如果分文件了,我觉得不用还沿用之前CS全局变量的做法了,以前的CS全局变量是为了实现按需加载,如果分文件了,可以支持import具体类就最好。

@Geequlim
Copy link
Contributor Author

还是通过CS全局来使用对应的功能,这块并没有任何差别。

拆分成多个文件要解决的问题是所有C#接口被放到了同一个文件内,然后每个人在生成api接口时的环境不一样导致TS代码在编译时会有问题。

比如负责Android的人不需要知道 iOS 那边的修改或 iOS 特定的API的存在,但在同一个项目中,他因为没有引入iOS的功能的情况下导致iOS相关的TS代码编译不通过。如果能够拆开,那么负责iOS的同事只需要将生成的对应的接口文件提交上来即可(我们目前是将生成的接口手动复制到单独的文件来解决此问题的)。

至于不用CS全局变量,采用 import 的方式引入对应接口,我认为是另一个课题了。

@Geequlim
Copy link
Contributor Author

在TS中引入C#的 api 这块我们确实也不喜欢通过全局的方式来访问。不过这个是可以通过 webpack 配置和其他现有的工具轻松解决的。

我们的项目中使用 C# 类型的引入方式与较早的 puerts 版本一致

import { DeadMosquito, System, tiny, Unity, UnityEngine } from 'csharp';

配置方式是添加一个这样的声明文件, 在 webpack将 csharp 配置为指向CS全局变量的 externals 即可。

  • puerts.d.ts
declare module "puerts" {
	export = puer;
}
declare module "csharp" {
	export = CS;
}

@chexiongsheng
Copy link
Collaborator

chexiongsheng commented Oct 29, 2024

我的意思是都要改这块的话,就没必要还用CS全局变量。不是通过declare module适配,而是直接不需要CS全局变量。

@chexiongsheng
Copy link
Collaborator

我的想法是直接类似这样
import Vector3 form 'csharp/UnityEngine/Vector3'

@Geequlim
Copy link
Contributor Author

个人认为这样的话工作量不少,而且会引入新问题。只是去掉全局CS污染而让现在非常方便的反射访问C#功能出现问题的话得不偿失。

  1. 如果没有生成 ts 接口的 C# 类型将无法访问到,如果能还需要进一步的功能开发
  2. 在开发过程中,我们希望直接在调试器的控制台中尝试使用C# api 进行测试,现在的 CS 全局变量很有用,并不希望它失效

@chexiongsheng
Copy link
Collaborator

那你这需求很简单吧?
每个类生成一个文件,按名字空间放到相应目录,然后根目录搞个index.d.ts引用这些文件就可以了吧?
///
...
这种感觉你们可以试试做下,pr过来。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants