Skip to content
This repository was archived by the owner on Feb 21, 2019. It is now read-only.

Commit d33283c

Browse files
committed
Merge pull request #68 from vthibault/memory-optimization
Memory optimization
2 parents efc853e + a821756 commit d33283c

File tree

7 files changed

+147
-71
lines changed

7 files changed

+147
-71
lines changed

src/Audio/SoundManager.js

Lines changed: 89 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -23,27 +23,32 @@ function( Client, Preferences, Memory )
2323
var _sounds = [];
2424

2525

26+
/**
27+
* Re-usable sounds
28+
*/
29+
var _cache = [];
30+
31+
2632
/**
2733
* @Constructor
2834
*/
29-
var Sound = {};
35+
var SoundManager = {};
3036

3137

3238
/**
3339
* @var {float} sound volume
3440
*
3541
*/
36-
Sound.volume = Preferences.Sound.volume;
42+
SoundManager.volume = Preferences.Sound.volume;
3743

3844

3945
/**
4046
* Play a wav sound
4147
*
4248
* @param {string} filename
4349
* @param {optional|number} vol (volume)
44-
* @param {optional|boolean} auto-repeat
4550
*/
46-
Sound.play = function play( filename, vol, repeat ) {
51+
SoundManager.play = function play( filename, vol ) {
4752
var volume;
4853

4954
// Sound volume * Global volume
@@ -59,30 +64,39 @@ function( Client, Preferences, Memory )
5964
return;
6065
}
6166

67+
// Re-usable sound
68+
var sound = getSoundFromCache(filename);
69+
if (sound) {
70+
sound.volume = Math.min(volume,1.0);
71+
sound._volume = volume;
72+
sound.tick = Date.now();
73+
sound.play();
74+
_sounds.push(sound);
75+
return;
76+
}
77+
6278
// Get the sound from client.
6379
Client.loadFile( 'data/wav/' + filename, function( url ) {
64-
var sound = document.createElement('audio');
80+
var i, count = _sounds.length;
81+
var sound, tick = Date.now();
82+
83+
// Wait a delay to replay a sound
84+
for (i = 0; i < count; ++i) {
85+
if (_sounds[i].src === url && _sounds[i].tick > tick - 100) {
86+
return;
87+
}
88+
}
6589

6690
// Initialiaze the sound and play it
91+
sound = document.createElement('audio');
6792
sound.filename = filename;
6893
sound.src = url;
94+
sound.tick = tick;
6995
sound.volume = Math.min(volume,1.0);
7096
sound._volume = volume;
71-
sound.play();
7297

73-
// Once the sound finish, remove it from memory
74-
sound.addEventListener('ended', function Remove(){
75-
var pos = _sounds.indexOf(this);
76-
if (pos !== -1) {
77-
if (repeat) {
78-
sound.currentTime = 0;
79-
sound.play();
80-
}
81-
else {
82-
_sounds.splice( pos, 1 );
83-
}
84-
}
85-
}, false);
98+
sound.addEventListener('ended', onSoundEnded, false);
99+
sound.play();
86100

87101
// Add it to the list
88102
_sounds.push(sound);
@@ -95,7 +109,7 @@ function( Client, Preferences, Memory )
95109
*
96110
* @param {optional|string} filename to stop
97111
*/
98-
Sound.stop = function stop( filename )
112+
SoundManager.stop = function stop( filename )
99113
{
100114
var i, count, list;
101115

@@ -130,7 +144,7 @@ function( Client, Preferences, Memory )
130144
*
131145
* @param {number} volume
132146
*/
133-
Sound.setVolume = function setVolume( volume )
147+
SoundManager.setVolume = function setVolume( volume )
134148
{
135149
var i, count = _sounds.length;
136150
this.volume = Math.min( volume, 1.0);
@@ -144,9 +158,62 @@ function( Client, Preferences, Memory )
144158
};
145159

146160

161+
/**
162+
* Move sound to cache.
163+
* ff we have a request to play the same sound again, get it back
164+
* Will avoid to re-create sound object at each request (re-usable object)
165+
*/
166+
function onSoundEnded()
167+
{
168+
var pos = _sounds.indexOf(this);
169+
170+
if (pos !== -1) {
171+
_sounds.splice( pos, 1);
172+
}
173+
174+
this.tick = Date.now();
175+
_cache.push(this);
176+
}
177+
178+
179+
/**
180+
* Remove sound from cache and return it
181+
* Check at the same time to remove sound not used since some times.
182+
*
183+
* @param {string} filename
184+
* @param {Audio} sound element
185+
*/
186+
function getSoundFromCache(filename)
187+
{
188+
var i, tick = Date.now(), count = _cache.length;
189+
var out = null;
190+
191+
for (i = 0; i < count; i++) {
192+
if (!out && _cache[i].filename === filename) {
193+
out = _cache[i];
194+
out.tick = tick;
195+
_cache.splice(i, 1);
196+
i--;
197+
count--;
198+
continue;
199+
}
200+
201+
// remove
202+
if (_cache[i].tick + 60000 < tick) {
203+
_cache.splice(i, 1);
204+
i--;
205+
count--;
206+
continue;
207+
}
208+
}
209+
210+
return out;
211+
}
212+
213+
147214
/**
148215
* Export
149216
*/
150-
return Sound;
217+
return SoundManager;
151218

152219
});

src/Controls/EntityControl.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -309,8 +309,8 @@ define(function( require )
309309
Session.moveAction = pkt;
310310

311311
pkt = new PACKET.CZ.REQUEST_MOVE();
312-
pkt.dest[0] = out[ count - 1 ][0];
313-
pkt.dest[1] = out[ count - 1 ][1];
312+
pkt.dest[0] = out[(count-1)*2 + 0];
313+
pkt.dest[1] = out[(count-1)*2 + 1];
314314
Network.sendPacket(pkt);
315315
return true;
316316
}

src/Engine/MapEngine/NPC.js

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -368,13 +368,7 @@ define(function( require )
368368
case 1:
369369
Sound.play( pkt.fileName );
370370
break;
371-
/*
372-
// Play repeat
373-
// Not supported !
374-
case 1:
375-
Sound.play( pkt.fileName, Sound.volume, true );
376-
break;
377-
*/
371+
378372
// From rathena, should stop a sound but doesn't seems to work in official client ?
379373
case 2:
380374
Sound.stop( pkt.fileName );

src/Engine/MapEngine/Skill.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -464,8 +464,8 @@ define(function( require )
464464

465465
// Move to position
466466
pkt = new PACKET.CZ.REQUEST_MOVE();
467-
pkt.dest[0] = out[ count - 1 ][0];
468-
pkt.dest[1] = out[ count - 1 ][1];
467+
pkt.dest[0] = out[(count-1)*2 + 0];
468+
pkt.dest[1] = out[(count-1)*2 + 1];
469469
Network.sendPacket(pkt);
470470
};
471471

@@ -524,8 +524,8 @@ define(function( require )
524524
// Save the packet and move to the position
525525
Session.moveAction = pkt;
526526
pkt = new PACKET.CZ.REQUEST_MOVE();
527-
pkt.dest[0] = out[ count - 1 ][0];
528-
pkt.dest[1] = out[ count - 1 ][1];
527+
pkt.dest[0] = out[(count-1)*2 + 0];
528+
pkt.dest[1] = out[(count-1)*2 + 1];
529529
Network.sendPacket(pkt);
530530
};
531531

src/Network/NetworkManager.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -322,8 +322,14 @@ define(function( require )
322322
}
323323

324324
// Parse packet
325-
var data = new packet.struct(fp, offset);
326-
console.log( '%c[Network] Recv:', 'color:#900090', data, packet.callback ? '' : '(no callback)' );
325+
if (!packet.instance) {
326+
packet.instance = new packet.struct(fp, offset);
327+
}
328+
else {
329+
packet.struct.call(packet.instance, fp, offset);
330+
}
331+
332+
console.log( '%c[Network] Recv:', 'color:#900090', packet.instance, packet.callback ? '' : '(no callback)' );
327333

328334
// Support for "0" type
329335
if (length) {
@@ -332,7 +338,7 @@ define(function( require )
332338

333339
// Call controller
334340
if (packet.callback) {
335-
packet.callback(data);
341+
packet.callback(packet.instance);
336342
}
337343
}
338344

src/Renderer/Entity/EntityWalk.js

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,11 @@ define( function( require )
3636
{
3737
this.speed = 150;
3838
this.tick = 0;
39-
this.path = [];
39+
this.path = new Int16Array(32*2);
4040
this.pos = new Float32Array(3);
4141
this.onEnd = null;
42+
this.index = 0;
43+
this.total = 0;
4244
}
4345

4446

@@ -51,23 +53,24 @@ define( function( require )
5153
* @param {number} to_y
5254
* @param {number} range optional
5355
*/
54-
function WalkTo( from_x, from_y, to_x, to_y, range )
56+
function walkTo( from_x, from_y, to_x, to_y, range )
5557
{
56-
var path = [];
57-
var count = PathFinding.search( from_x | 0, from_y | 0, to_x | 0, to_y | 0, range || 0, path );
58+
var path = this.walk.path;
59+
var total = PathFinding.search( from_x | 0, from_y | 0, to_x | 0, to_y | 0, range || 0, path);
5860

59-
if (count) {
60-
path.length = count;
61-
path.shift();
61+
this.walk.index = 1 * 2; // skip first index
62+
this.walk.total = total * 2;
6263

63-
if (count === 2 && path[0][0] === from_x && path[0][1] === from_y){
64+
if (total) {
65+
// Same position
66+
if (total === 2 &&
67+
path[this.walk.index+0] === from_x &&
68+
path[this.walk.index+1] === from_y){
6469
return;
6570
}
6671

6772
this.walk.pos.set(this.position);
68-
this.walk.path = path;
6973
this.walk.tick = Renderer.tick;
70-
7174
this.headDir = 0;
7275

7376
if (this.action !== this.ACTION.WALK) {
@@ -85,22 +88,24 @@ define( function( require )
8588
/**
8689
* Process walking
8790
*/
88-
function WalkProcess()
91+
function walkProcess()
8992
{
9093
var pos = this.position;
9194
var walk = this.walk;
9295
var path = walk.path;
96+
var index = walk.index;
97+
var total = walk.total;
9398

9499
var x, y, speed;
95100
var TICK = Renderer.tick;
96101
var delay = 0;
97102

98-
if (path.length) {
103+
if (index < total) {
99104

100105
// Calculate new position, base on time and walk speed.
101-
while (path.length) {
102-
x = path[0][0] - (walk.pos[0]);
103-
y = path[0][1] - (walk.pos[1]);
106+
while (index < total) {
107+
x = path[index+0] - (walk.pos[0]);
108+
y = path[index+1] - (walk.pos[1]);
104109

105110
// Seems like walking on diagonal is slower ?
106111
speed = ( x && y ) ? walk.speed / 0.6 : walk.speed;
@@ -111,13 +116,16 @@ define( function( require )
111116
}
112117

113118
walk.tick += speed;
114-
walk.pos.set(path.shift());
119+
walk.pos[0] = path[index+0];
120+
walk.pos[1] = path[index+1];
121+
index += 2;
115122
}
116123

117124
// Calculate and store new position
118125
// TODO: check the min() part.
119126

120-
delay = Math.min(speed, TICK-walk.tick);
127+
delay = Math.min(speed, TICK-walk.tick);
128+
walk.index = index;
121129

122130
// Should not happened, avoid division by 0
123131
if (!delay) {
@@ -129,7 +137,7 @@ define( function( require )
129137
pos[2] = Altitude.getCellHeight( pos[0], pos[1] );
130138

131139
// Update player direction while walking
132-
if (path.length) {
140+
if (index < total) {
133141
this.direction = DIRECTION[(x>0?1:x<0?-1:0)+1][(y>0?1:y<0?-1:0)+1];
134142
return;
135143
}
@@ -165,8 +173,8 @@ define( function( require )
165173
{
166174
this.onWalkEnd = function onWalkEnd(){};
167175
this.walk = new WalkStructure();
168-
this.walkTo = WalkTo;
169-
this.walkProcess = WalkProcess;
176+
this.walkTo = walkTo;
177+
this.walkProcess = walkProcess;
170178
};
171179
});
172180

0 commit comments

Comments
 (0)