@@ -47,59 +47,78 @@ export class Slide {
47
47
}
48
48
}
49
49
50
- public static create ( cursor : Canvas , declaration : SlideDeclaration ) : Slide {
50
+ public static create ( cursor ? : Canvas , declaration ? : SlideDeclaration ) : Slide {
51
51
return new this ( cursor , declaration ) ;
52
52
}
53
53
54
- public static fromObject ( obj : SlideDeclaration , cursor : Canvas ) : Slide {
54
+ public static fromObject ( obj : SlideDeclaration , cursor ? : Canvas ) : Slide {
55
55
return this . create ( cursor , obj ) ;
56
56
}
57
57
58
- public static fromJSON ( json : string , cursor : Canvas ) : Slide {
58
+ public static fromJSON ( json : string , cursor ? : Canvas ) : Slide {
59
59
return this . fromObject ( JSON . parse ( json ) , cursor ) ;
60
60
}
61
61
62
62
public addShape ( name : string , shape : ShapeRenderable , toOverride = false ) : void {
63
63
if ( this . shapes . has ( name ) && ! toOverride ) {
64
- throw new Error ( `Shape "${ name } " already exists in slide "${ this . name } "` ) ;
64
+ throw new Error (
65
+ `You are trying to add shape with the name "${ name } " into the slide "${ this . name } ". ` +
66
+ `But this shape already exists in slide "${ this . name } ".`
67
+ ) ;
65
68
}
66
69
67
70
this . shapes . set ( name , shape ) ;
68
71
}
69
72
70
73
public addAnimation ( name : string , animation : Animationable , toOverride = false ) : void {
71
74
if ( this . animations . has ( name ) && ! toOverride ) {
72
- throw new Error ( `Animation "${ name } " already exists in slide "${ this . name } "` ) ;
75
+ throw new Error (
76
+ `You are trying to add animation with the name "${ name } " into the slide "${ this . name } ". ` +
77
+ `But this animation already exists in slide "${ this . name } ".`
78
+ ) ;
73
79
}
74
80
75
81
this . animations . set ( name , animation ) ;
76
82
}
77
83
78
84
public addOrder ( shape : string , animations : string [ ] = [ ] ) : void {
79
- if ( this . order . some ( ( order : OrderDeclaration ) => order . shape === shape ) ) {
80
- throw new Error ( `You already have an ordering for shape "${ shape } " in slide "${ this . name } "` ) ;
85
+ if ( this . order . some ( ( order ) => order . shape === shape ) ) {
86
+ throw new Error (
87
+ `You already have specified an ordering for shape "${ shape } " in slide "${ this . name } ". ` +
88
+ 'Adding another one with the same name does not make any sense. ' +
89
+ 'Did you make a typo in shape name or forgot that you already added a shape to ordering?'
90
+ ) ;
91
+ }
92
+
93
+ const unknownAnimations = animations . filter ( ( animation ) => ! this . animations . has ( animation ) ) ;
94
+ if ( unknownAnimations . length > 0 ) {
95
+ throw new Error (
96
+ `You have provided animations for the shape "${ shape } " in slide "${ this . name } ". ` +
97
+ `But, some of them could not be found in the slide "${ this . name } ". ` +
98
+ `These animations are: [${ unknownAnimations . join ( ', ' ) } ]. ` +
99
+ `Please, check if the animations from the list are declared in slide "${ this . name } ".`
100
+ ) ;
81
101
}
82
102
83
103
this . order . push ( { animations, shape } ) ;
84
104
}
85
105
86
- // eslint-disable-next-line max-statements
87
106
public async render ( ) : Promise < void > {
88
- const { shapes } = this ;
89
- const { animations } = this ;
107
+ const { animations, shapes } = this ;
90
108
const shapesToRender : ShapeRenderable [ ] = [ ] ;
91
109
const sequence : Array < ( ) => void > = [ ] ;
110
+ const onTick = ( ) : void => this . renderShapes ( shapesToRender ) ;
92
111
93
112
// We need to re-render shapes each time when some of the animations made a tick
94
113
// Hence, made an update in shape properties that we need to reflect on canvas
95
- animations . forEach ( ( animation : Animationable ) => animation . on ( 'tick' , ( ) => this . renderShapes ( shapesToRender ) ) ) ;
114
+ animations . forEach ( ( animation ) => animation . on ( 'tick' , onTick ) ) ;
96
115
97
116
for ( const order of this . order ) {
98
117
const shapeToRender = shapes . get ( order . shape ) ;
99
118
if ( typeof shapeToRender === 'undefined' ) {
100
119
throw new Error (
101
120
`You specified shape "${ order . shape } " in slide "${ this . name } " ` +
102
- 'as part of ordering, but it does not exist in shapes declaration.\n ' +
121
+ 'as part of ordering, but it does not exist in shapes declaration for the slide. ' +
103
122
'Maybe you forgot to create a shape you want to order or it is a typo in ordering itself.'
104
123
) ;
105
124
}
@@ -117,9 +136,9 @@ export class Slide {
117
136
}
118
137
119
138
// When all of the rendering and animation is done - we can freely remove the listeners from animations
120
- sequence . push ( ( ) => animations . forEach ( ( animation : Animationable ) => animation . removeAllListeners ( ) ) ) ;
139
+ sequence . push ( ( ) => animations . forEach ( ( animation ) => animation . removeListener ( 'tick' , onTick ) ) ) ;
121
140
122
- // We can't allow Promise.all() here or anything that could render the shapes concurrently or parallel
141
+ // We can't allow Promise.all() here or anything that could render the shapes concurrently
123
142
// Hence, we need to reduce the sequence to the chain of promises, so we can get waterfall rendering
124
143
return await sequence . reduce ( async ( promise , item ) => await promise . then ( item ) , Promise . resolve ( ) ) ;
125
144
}
@@ -141,12 +160,14 @@ export class Slide {
141
160
}
142
161
143
162
private initShapes ( declaration : ShapeDeclaration [ ] ) : void {
144
- declaration . forEach ( ( shapeDeclaration : ShapeDeclaration ) => {
163
+ declaration . forEach ( ( shapeDeclaration ) => {
145
164
const ctor = SHAPES . get ( shapeDeclaration . type as ShapeType ) ;
146
165
147
166
if ( typeof ctor === 'undefined' ) {
148
167
throw new Error (
149
- `Shape "${ shapeDeclaration . name } " (${ shapeDeclaration . type } ) is unknown for me, maybe you made a typo?`
168
+ `You have specified a shape with the name "${ shapeDeclaration . name } " in slide "${ this . name } ". ` +
169
+ `This shape has an unknown type "${ shapeDeclaration . type } ". ` +
170
+ 'Maybe you made a typo in "type" or tried to use a shape we do not have implemented.'
150
171
) ;
151
172
}
152
173
@@ -155,13 +176,14 @@ export class Slide {
155
176
}
156
177
157
178
private initAnimations ( declaration : AnimationDeclaration [ ] ) : void {
158
- declaration . forEach ( ( animationDeclaration : AnimationDeclaration ) => {
179
+ declaration . forEach ( ( animationDeclaration ) => {
159
180
const ctor = ANIMATIONS . get ( animationDeclaration . type as AnimationType ) ;
160
181
161
182
if ( typeof ctor === 'undefined' ) {
162
183
throw new Error (
163
- `Animation "${ animationDeclaration . name } " (${ animationDeclaration . type } ) is unknown for me, ` +
164
- 'maybe you made a typo?'
184
+ `You have specified an animation with the name "${ animationDeclaration . name } " in slide "${ this . name } ". ` +
185
+ `This animation has an unknown type "${ animationDeclaration . type } ". ` +
186
+ 'Maybe you made a typo in "type" or tried to use an animation we do not have implemented.'
165
187
) ;
166
188
}
167
189
@@ -171,7 +193,7 @@ export class Slide {
171
193
172
194
private renderShapes ( shapes : ShapeRenderable [ ] ) : void {
173
195
this . cursor . eraseScreen ( ) ;
174
- shapes . forEach ( ( shape : ShapeRenderable ) => shape . render ( this . cursor ) ) ;
196
+ shapes . forEach ( ( shape ) => shape . render ( this . cursor ) ) ;
175
197
this . cursor . flush ( ) ;
176
198
}
177
199
}
0 commit comments