Skip to content

Commit

Permalink
Avoid instanceof keyword. Use isCategory() instead.
Browse files Browse the repository at this point in the history
Supports our previous discussion and PR:
#1096
#1098
  • Loading branch information
ronyeh committed Jan 19, 2022
1 parent f5c1a33 commit 151e452
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 38 deletions.
18 changes: 9 additions & 9 deletions src/annotation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ import { Stave } from './stave';
import { Stem } from './stem';
import { StemmableNote } from './stemmablenote';
import { Tables } from './tables';
import { TabNote } from './tabnote';
import { TextFormatter } from './textformatter';
import { Category } from './typeguard';
import { Category, isStemmableNote, isTabNote } from './typeguard';
import { log } from './util';

// eslint-disable-next-line
Expand Down Expand Up @@ -86,7 +85,8 @@ export class Annotation extends Modifier {
const stemDirection = note.hasStem() ? note.getStemDirection() : Stem.UP;
let stemHeight = 0;
let lines = 5;
if (note instanceof TabNote) {

if (isTabNote(note)) {
if (note.render_options.draw_stem) {
const stem = (note as StemmableNote).getStem();
if (stem) {
Expand All @@ -95,8 +95,8 @@ export class Annotation extends Modifier {
} else {
stemHeight = 0;
}
} else if (note instanceof StemmableNote) {
const stem = (note as StemmableNote).getStem();
} else if (isStemmableNote(note)) {
const stem = note.getStem();
if (stem && note.getNoteType() === 'n') {
stemHeight = Math.abs(stem.getHeight()) / Tables.STAVE_LINE_DISTANCE;
}
Expand All @@ -110,8 +110,8 @@ export class Annotation extends Modifier {

if (annotation.verticalJustification === this.VerticalJustify.TOP) {
let noteLine = note.getLineNumber(true);
if (note instanceof TabNote) {
noteLine = lines - ((note as TabNote).leastString() - 0.5);
if (isTabNote(note)) {
noteLine = lines - (note.leastString() - 0.5);
}
if (stemDirection === Stem.UP) {
noteLine += stemHeight;
Expand All @@ -127,8 +127,8 @@ export class Annotation extends Modifier {
}
} else if (annotation.verticalJustification === this.VerticalJustify.BOTTOM) {
let noteLine = lines - note.getLineNumber();
if (note instanceof TabNote) {
noteLine = (note as TabNote).greatestString() - 1;
if (isTabNote(note)) {
noteLine = note.greatestString() - 1;
}
if (stemDirection === Stem.DOWN) {
noteLine += stemHeight;
Expand Down
7 changes: 4 additions & 3 deletions src/articulation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { Stave } from './stave';
import { Stem } from './stem';
import { StemmableNote } from './stemmablenote';
import { Tables } from './tables';
import { Category, isGraceNote, isStaveNote, isTabNote } from './typeguard';
import { Category, isGraceNote, isStaveNote, isStemmableNote, isTabNote } from './typeguard';
import { defined, log, RuntimeError } from './util';

export interface ArticulationStruct {
Expand Down Expand Up @@ -218,8 +218,9 @@ export class Articulation extends Modifier {
const stemDirection = note.hasStem() ? note.getStemDirection() : Stem.UP;
let stemHeight = 0;
// Decide if we need to consider beam direction in placement.
if (note instanceof StemmableNote) {
const stem = (note as StemmableNote).getStem();

if (isStemmableNote(note)) {
const stem = note.getStem();
if (stem) {
stemHeight = Math.abs(stem.getHeight()) / Tables.STAVE_LINE_DISTANCE;
}
Expand Down
8 changes: 4 additions & 4 deletions src/bend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ import { FontInfo } from './font';
import { Modifier } from './modifier';
import { ModifierContextState } from './modifiercontext';
import { Tables } from './tables';
import { TabNote } from './tabnote';
import { Category } from './typeguard';
import { Category, isTabNote } from './typeguard';
import { RuntimeError } from './util';

export interface BendPhrase {
Expand Down Expand Up @@ -44,8 +43,9 @@ export class Bend extends Modifier {
for (let i = 0; i < bends.length; ++i) {
const bend = bends[i];
const note = bend.checkAttachedNote();
if (note instanceof TabNote) {
const stringPos = (note as TabNote).leastString() - 1;

if (isTabNote(note)) {
const stringPos = note.leastString() - 1;
if (state.top_text_line < stringPos) {
state.top_text_line = stringPos;
}
Expand Down
5 changes: 2 additions & 3 deletions src/ghostnote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@
//
// ## Description

import { Annotation } from './annotation';
import { ModifierContext } from './modifiercontext';
import { NoteStruct } from './note';
import { Stave } from './stave';
import { StemmableNote } from './stemmablenote';
import { Category } from './typeguard';
import { Category, isAnnotation } from './typeguard';
import { RuntimeError } from './util';

const ERROR_MSG = 'Ghost note must have valid initialization data to identify duration.';
Expand Down Expand Up @@ -67,7 +66,7 @@ export class GhostNote extends StemmableNote {
this.setRendered();
for (let i = 0; i < this.modifiers.length; ++i) {
const modifier = this.modifiers[i];
if (modifier instanceof Annotation) {
if (isAnnotation(modifier)) {
modifier.setContext(this.getContext());
modifier.drawWithStyle();
}
Expand Down
5 changes: 2 additions & 3 deletions src/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import { CanvasContext } from './canvascontext';
import { RenderContext } from './rendercontext';
import { SVGContext } from './svgcontext';
import { isRenderContext } from './typeguard';
import { RuntimeError } from './util';
import { isHTMLCanvas, isHTMLDiv } from './web';

Expand Down Expand Up @@ -112,10 +113,8 @@ export class Renderer {
constructor(context: RenderContext);
constructor(canvas: string | HTMLCanvasElement | HTMLDivElement, backend: number);
constructor(arg0: string | HTMLCanvasElement | HTMLDivElement | RenderContext, arg1?: number) {
if (arg0 instanceof RenderContext) {
if (isRenderContext(arg0)) {
// The user has provided what looks like a RenderContext, let's just use it.
// TODO(tommadams): RenderContext is an interface, can we introduce a context base class
// to make this check more robust?
this.ctx = arg0;
} else {
if (arg1 === undefined) {
Expand Down
35 changes: 19 additions & 16 deletions src/typeguard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@
// Author: Ron B. Yeh
// MIT License

import { Accidental } from './accidental.js';
import { Dot } from './dot.js';
import { GraceNote } from './gracenote.js';
import { GraceNoteGroup } from './gracenotegroup.js';
import { Note } from './note.js';
import { Barline } from './stavebarline.js';
import { StaveNote } from './stavenote.js';
import { StemmableNote } from './stemmablenote.js';
import { TabNote } from './tabnote.js';
import { Accidental } from './accidental';
import { Annotation } from './annotation';
import { Dot } from './dot';
import { GraceNote } from './gracenote';
import { GraceNoteGroup } from './gracenotegroup';
import { Note } from './note';
import { RenderContext } from './rendercontext.js';
import { Barline } from './stavebarline';
import { StaveNote } from './stavenote';
import { StemmableNote } from './stemmablenote';
import { TabNote } from './tabnote';

/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
/* eslint-disable @typescript-eslint/ban-types */

/**
* Use instead of `instanceof` as a more flexible type guard.
Expand Down Expand Up @@ -52,15 +52,17 @@ export function isCategory<T>(obj: any, category: string, checkAncestors: boolea
}
}

export const isStemmableNote = (obj: unknown): obj is StemmableNote => isCategory(obj, Category.StemmableNote);
export const isStaveNote = (obj: unknown): obj is StaveNote => isCategory(obj, Category.StaveNote);
export const isBarline = (obj: unknown): obj is Barline => isCategory(obj, Category.Barline);
export const isAccidental = (obj: unknown): obj is Accidental => isCategory(obj, Category.Accidental);
export const isAnnotation = (obj: unknown): obj is Annotation => isCategory(obj, Category.Annotation);
export const isBarline = (obj: unknown): obj is Barline => isCategory(obj, Category.Barline);
export const isDot = (obj: unknown): obj is Dot => isCategory(obj, Category.Dot);
export const isGraceNote = (obj: unknown): obj is GraceNote => isCategory(obj, Category.GraceNote);
export const isGraceNoteGroup = (obj: unknown): obj is GraceNoteGroup => isCategory(obj, Category.GraceNoteGroup);
export const isTabNote = (obj: unknown): obj is TabNote => isCategory(obj, Category.TabNote);
export const isDot = (obj: unknown): obj is Dot => isCategory(obj, Category.Dot);
export const isNote = (obj: unknown): obj is Note => isCategory(obj, Category.Note);
export const isRenderContext = (obj: unknown): obj is RenderContext => isCategory(obj, Category.RenderContext);
export const isStaveNote = (obj: unknown): obj is StaveNote => isCategory(obj, Category.StaveNote);
export const isStemmableNote = (obj: unknown): obj is StemmableNote => isCategory(obj, Category.StemmableNote);
export const isTabNote = (obj: unknown): obj is TabNote => isCategory(obj, Category.TabNote);

// 'const' enums are erased by the TypeScript compiler. The string values are inlined at all the use sites.
// See: https://www.typescriptlang.org/docs/handbook/enums.html#const-enums
Expand Down Expand Up @@ -97,6 +99,7 @@ export const enum Category {
Ornament = 'Ornament',
Parenthesis = 'Parenthesis',
PedalMarking = 'PedalMarking',
RenderContext = 'RenderContext',
RepeatNote = 'RepeatNote',
Repetition = 'Repetition',
Stave = 'Stave',
Expand Down
6 changes: 6 additions & 0 deletions tests/typeguard_tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ function real(): void {
ok(isNote(s), 'StaveNote extends StemmableNote which extends Note, so s is a Note');
ok(isStemmableNote(t), 'TabNote extends StemmableNote');
ok(isNote(t), 'TabNote extends StemmableNote which extends Note, so t is a Note');

const canvas = document.createElement('canvas');
canvas.width = 800;
canvas.height = 400;
const ctx = new CanvasContext(canvas.getContext('2d') as CanvasRenderingContext2D);
ok(isRenderContext(ctx), 'ctx is a RenderContext');
}

/**
Expand Down

0 comments on commit 151e452

Please sign in to comment.