Skip to content

Commit 5c93a23

Browse files
committed
[F] 修一下单文件exe模式的版本号适配等
1 parent 864342e commit 5c93a23

3 files changed

Lines changed: 21 additions & 4 deletions

File tree

Program.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,10 @@ private static int Main(string[] args)
3636

3737
private static Command BuildRootCommand()
3838
{
39-
var root = new RootCommand($"MuConvert {Utils.AppVersion} — simai / maidata → MA2")
39+
var root = new RootCommand
4040
{
41-
Description = "将 .txt 格式的 simai 单谱或 maidata 转为 MA2,输出与输入同目录的 lv_N.ma2。"
41+
Description = $"MuConvert {Utils.AppVersion} — simai / maidata → MA2\n" +
42+
"将 .txt 格式的 simai 单谱或 maidata 转为 MA2,输出与输入同目录的 lv_N.ma2。"
4243
};
4344

4445
var levelsOption = new Option<string?>("--levels", "-l")

README.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@
1818
- 从源语言到IR的过程,即parser,确保是**无损**的、可以记录下来关于这个谱面的所有信息。这样可以有利于维护,也为将来的发展提供了更大的可扩展性。
1919
- 而在从IR到目标语言的过程,即genertaor,则会根据目标语言的表达能力,进行必要的**近似**,所有的信息丢失都发生在generator中。
2020

21+
### 编译为单文件exe模式
22+
> 这样就不用带着一堆依赖一起发给别人了,只发一个exe就行。
23+
```shell
24+
dotnet publish -c Release -r win-x64 -p:SelfContained=false -p UseAppHost=true -p:PublishSingleFile=true
25+
```
26+
注意:以上命令以Release模式编译,且设置了`SelfContained=false`,即不会把.NET运行时打包进来,这样出来的exe只有几M大,但要求用户电脑上必须有.NET 10 Runtime才能运行。
27+
如果有必要,可自行将`SelfContained`改为true,这样就会打包一个完整的.NET运行时进去(出来的exe有大几十M),但是确保用户可以运行。
28+
2129
### 关于时间格式
2230
- 与其他库可能有所不同的一点是,本程序的底层使用“小节时间”(`Bar`)作为核心的时间格式表示。
2331
- “小节时间”是一个**分数**,指从谱面开头所经过的小节数。
@@ -29,4 +37,12 @@
2937
- 举一个具体的例子:对下述的总长为一小节、但横跨120BPM和60BPM区间的星星,
3038
-`(120){2}1h[1:1],(60){2},``simai`中这个hold的时长是120BPM下的1小节即2s;
3139
- 然而对看似等价的表述`BPM 0 0 120; BPM 0 192 60; NMHLD 0 0 0 384`,这个hold的持续时长是它落在120BPM的那半小节(1s)+落在60BPM的那半小节(2s),总共是3s。
32-
- 因此,在`Duration`中会进一步的把底层的数据存储类型分为`Bar``InvarientBar`,对应于以上的两种情况。
40+
- 因此,在`Duration`中会进一步的把底层的数据存储类型分为`Bar``InvarientBar`,对应于以上的两种情况。
41+
42+
### 关于parser的技术选型
43+
- SimaiParser,考虑到Simai是一个相对复杂的格式化语法、本质是一种DSL,所以采用了[ANTLR](https://github.com/antlr/antlr4/blob/master/doc/index.md)进行解析。
44+
- ANTLR的核心是`g4`语法文件,因此在我们的代码里编写了针对Simai语言的语法定义文件:`Simai.g4`。如需修改,请自行学习ANTLR的文档。
45+
- ANTLR本身是不特定于编程语言的(它提供了各种编程语言的SDK),而语法文件的作用是,会被用于生成目标编程语言的“解析器代码”,以供调用。
46+
-`MuConvert.csproj`中定义了一个`<Antlr4>`的Item,它就是用来在编译时添加一个从语法文件生成C#解析器代码的编译步骤的。生成的文件会被自动放在`obj`目录下。
47+
- 具体的原理,请详见`parser/simai/SimaiParser.cs`中,对`MuConvert.antlr`下的各个类的引用。
48+
- MA2的话,由于其天生就是为了机读设计的、格式相对简单,没有必要上ANTLR;而是直接逐行读取、一行内`Split('\t')`,就足以解析MA2的所有内容了。

utils/Utils.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public static Exception Fail(string msg = "")
1717
return new Exception(string.Format(Locale.AssertionFailed, msg));
1818
}
1919

20-
public static string AppVersion => FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).ProductVersion?[..^33] ?? "unknown";
20+
public static string AppVersion => Assembly.GetExecutingAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion[..^33] ?? "unknown";
2121

2222
public static void SetLocale(CultureInfo culture) => Locale.Culture = culture;
2323

0 commit comments

Comments
 (0)