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

Use const enum to have readable glyph names that are inlined as unicode code points and unicode strings during compilation. #30

Closed
wants to merge 1 commit into from

Conversation

ronyeh
Copy link
Member

@ronyeh ronyeh commented Jul 24, 2023

This is a work in progress as I have discovered some issues with our use of const enums, and how it may conflict with the way we compile our library.

Anyways.... at least in the ES modules output, this works perfectly fine.

This PR adds two const enums, SMuFLGlyph and SMuFLCodePoint, which contain all the smufl glyphs and hex code points.

The big idea is that in our code, we can use readable names like: SMuFLGlyph.csymMinor

The compiled output should ideally make no reference to these enums. All uses of the enums should be erased and replaced by their values (similar in spirit to C preprocessor #define constants).

So SMuFLGlyph.csymMinor => "\uE874".

I have verified that this works great in the ESM build of our library. This means we do not need to use String.fromCharCode(), which allows us to avoid the issues noted in #29 .

By using these const enums, we will be using the unicode characters directly. No extra step in translating the code points to characters.

If for some reason we really do need the code point, this PR includes a const enum of all the code points (SMuFLCodePoint).

I'd like to hear any and all comments... both for an against this approach. :-)

unicode code points and unicode strings during compilation.
@ronyeh
Copy link
Member Author

ronyeh commented Jul 24, 2023

The biggest drawback right now is that our webpack exports do not erase the const enums... and the enums are treated as regular enums.

We have used const enums in the past.... so it's possible that we haven't been getting the "full performance benefit" of those const enums.

It is possible that our efforts to speed up our build (by setting transpileOnly: true) is breaking the const enums. See: microsoft/TypeScript#16671 (comment)

Regardless, it would be super cool if we could figure this out.

Maybe the right answer is to emit ES modules first, and then run the webpack build process on the ESM files? That way, we are "compiling" the ESM files, which already have the const enums erased.

@ronyeh
Copy link
Member Author

ronyeh commented Jul 24, 2023

Even if we don't go with the const enum approach in the end, I believe we can avoid converting code points to strings in most cases.

We should just use unicode string literals like: '\uE874'.

@ronyeh
Copy link
Member Author

ronyeh commented Jul 24, 2023

Remember that the '\uXXXX' escape code only works for code points less than or equal to 0xFFFF. For bigger code points, we need to use this form:

'\u{1d12b}'
// accidentalDoubleFlat alternate code point is > 0xFFFF

@@ -8,7 +8,7 @@ import { Dot } from './dot';
import { GraceNote } from './gracenote';
import { GraceNoteGroup } from './gracenotegroup';
import { Note } from './note';
import { RenderContext } from './rendercontext.js';
import { RenderContext } from './rendercontext';
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fixes an error in the import. It should not include the .js extension.

@@ -360,7 +361,7 @@ export class ChordSymbol extends Modifier {
symbolModifier: SymbolModifiers;
}> = {}
): this {
return this.addText(String.fromCharCode(0xe874 /*csymMinor*/, 0xe874 /*csymMinor*/), params);
return this.addText(SMuFLGlyph.csymMinor + SMuFLGlyph.csymMinor, params);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the ESM build, this line is successfully changed to:

return this.addText("\uE874" + "\uE874", params);

@@ -4,7 +4,6 @@
import { Bend } from './bend';
import { Modifier } from './modifier';
import { ModifierContext, ModifierContextState } from './modifiercontext';
import { RenderContext } from './rendercontext';
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused import.

@@ -67,11 +69,11 @@ function harsh(options: TestOptions, contextBuilder: ContextBuilder): void {
{ str: 4, fret: 9 },
],
duration: 'h',
}).addModifier(new Vibrato().setVibratoCode(0xeae2), 0),
}).addModifier(new Vibrato().setVibratoCode(SMuFLCodePoint.wiggleVibratoLargeFastest /* 0xeae2 */), 0),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rvilarl Should we be relying on code points? Why not just accept the unicode character directly?

In this case, we would use: '\ueae2'

@rvilarl
Copy link
Collaborator

rvilarl commented Jul 24, 2023

Hi Ron,
I agree that we should move to the scape codes. The enums are no doubt easier to understand but we should make sure that the size of the library does not grow too much. The new file is very big.

@ronyeh
Copy link
Member Author

ronyeh commented Jul 24, 2023 via email

@ronyeh
Copy link
Member Author

ronyeh commented Jul 24, 2023

https://github.com/evanw/esbuild/blob/main/CHANGELOG-2021.md#0149

Maybe we will have to switch from webpack to esbuild to make it work.

There might be a webpack plugin, but I am also a fan of esbuild for other reasons so maybe it is worth the trouble.

@ronyeh
Copy link
Member Author

ronyeh commented Aug 1, 2023

Closing this one for now, but I have been investigating esbuild in another branch and it is very promising.

  1. It's fast.
  2. It seems to handle const enums in the way we expect.

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

Successfully merging this pull request may close these issues.

None yet

2 participants