new file: Files/flashplayer_32_sa.exe new file: favicon.ico new file: globe.gif new file: imgs/download.png new file: imgs/zuck.jpg new file: index.html new file: other.ico new file: script.js new file: site.webmanifest new file: sitemap.html new file: styles/backround.css new file: styles/border.css new file: styles/fonts/Titillium_Web/OFL.txt new file: styles/fonts/Titillium_Web/TitilliumWeb-Black.ttf new file: styles/fonts/Titillium_Web/TitilliumWeb-Bold.ttf new file: styles/fonts/Titillium_Web/TitilliumWeb-BoldItalic.ttf new file: styles/fonts/Titillium_Web/TitilliumWeb-ExtraLight.ttf new file: styles/fonts/Titillium_Web/TitilliumWeb-ExtraLightItalic.ttf new file: styles/fonts/Titillium_Web/TitilliumWeb-Italic.ttf new file: styles/fonts/Titillium_Web/TitilliumWeb-Light.ttf new file: styles/fonts/Titillium_Web/TitilliumWeb-LightItalic.ttf new file: styles/fonts/Titillium_Web/TitilliumWeb-Regular.ttf new file: styles/fonts/Titillium_Web/TitilliumWeb-SemiBold.ttf new file: styles/fonts/Titillium_Web/TitilliumWeb-SemiBoldItalic.ttf new file: styles/fonts/webfontkit-20221027-163353/generator_config.txt new file: styles/fonts/webfontkit-20221027-163353/specimen_files/grid_12-825-55-15.css new file: styles/fonts/webfontkit-20221027-163353/specimen_files/specimen_stylesheet.css new file: styles/fonts/webfontkit-20221027-163353/stylesheet.css new file: styles/fonts/webfontkit-20221027-163353/titilliumweb-extralight-demo.html new file: styles/fonts/webfontkit-20221027-163353/titilliumweb-extralight-webfont.woff new file: styles/fonts/webfontkit-20221027-163353/titilliumweb-extralight-webfont.woff2 new file: styles/fonts/webfontkit-20221027-165950/generator_config.txt new file: styles/fonts/webfontkit-20221027-165950/specimen_files/grid_12-825-55-15.css new file: styles/fonts/webfontkit-20221027-165950/specimen_files/specimen_stylesheet.css new file: styles/fonts/webfontkit-20221027-165950/stylesheet.css new file: styles/fonts/webfontkit-20221027-165950/titilliumweb-bold-demo.html new file: styles/fonts/webfontkit-20221027-165950/titilliumweb-bold-webfont.woff new file: styles/fonts/webfontkit-20221027-165950/titilliumweb-bold-webfont.woff2 new file: styles/style.css new file: tools/2048/.gitignore new file: tools/2048/.jshintrc new file: tools/2048/CONTRIBUTING.md new file: tools/2048/LICENSE.txt new file: tools/2048/README.md new file: tools/2048/Rakefile new file: tools/2048/favicon.ico new file: tools/2048/index.html new file: tools/2048/js/animframe_polyfill.js new file: tools/2048/js/application.js new file: tools/2048/js/bind_polyfill.js new file: tools/2048/js/classlist_polyfill.js new file: tools/2048/js/game_manager.js new file: tools/2048/js/grid.js new file: tools/2048/js/html_actuator.js new file: tools/2048/js/keyboard_input_manager.js new file: tools/2048/js/local_storage_manager.js new file: tools/2048/js/tile.js new file: tools/2048/meta/apple-touch-icon.png new file: tools/webretro/cores/neocd_libretro.js new file: tools/webretro/cores/neocd_libretro.wasm new file: tools/webretro/cores/nestopia_libretro.js new file: tools/webretro/cores/nestopia_libretro.wasm new file: tools/webretro/cores/o2em_libretro.js new file: tools/webretro/cores/o2em_libretro.wasm new file: tools/webretro/cores/opera_libretro.js new file: tools/webretro/cores/opera_libretro.wasm
543 lines
15 KiB
JavaScript
543 lines
15 KiB
JavaScript
/**
|
|
* gamecore.js - Copyright 2012 Playcraft Labs, Inc. (see licence.txt)
|
|
* pool.js
|
|
*/
|
|
|
|
/**
|
|
* @class gamecore.Pool
|
|
* Easy (high-performance) object pooling
|
|
*
|
|
* A pool of objects for use in situations where you want to minimize object life cycling (and
|
|
* subsequently garbage collection). It also serves as a very high speed, minimal overhead
|
|
* collection for small numbers of objects.
|
|
* <p>
|
|
* This class maintains mutual an array of objects which are free. If you wish to maintain a list of both
|
|
* free and used then see the gamecore.DualPool.
|
|
* <p>
|
|
* Pools are managed by class type, and will auto-expand as required. You can create a custom initial pool
|
|
* size by deriving from the Pool class and statically overriding INITIAL_POOL_SIZE.
|
|
* <p>
|
|
* Keep in mind that objects that are pooled are not constructed; they are "reset" when handed out.
|
|
* You need to "acquire" one and then reset its state, usually via a static create factory method.
|
|
* <p>
|
|
* Example:
|
|
* <code>
|
|
* Point = gamecore.Pooled('Point',
|
|
* {
|
|
* // Static constructor
|
|
* create:function (x, y)
|
|
* {
|
|
* var n = this._super();
|
|
* n.x = x;
|
|
* n.y = y;
|
|
* return n;
|
|
* }
|
|
* },
|
|
* {
|
|
* x:0, y:0, // instance
|
|
*
|
|
* init: function(x, y)
|
|
* {
|
|
* this.x = x;
|
|
* this.y = y;
|
|
* }
|
|
* }
|
|
* </code>
|
|
* To then access the object from the pool, use create, instead of new. Then release it.
|
|
* <code>
|
|
* var p = Point.create(100, 100);
|
|
* // ... do something
|
|
* p.release();
|
|
* </code>
|
|
*
|
|
*/
|
|
|
|
gamecore.Pool = gamecore.Base.extend('gamecore.Pool',
|
|
{
|
|
INITIAL_POOL_SIZE:1,
|
|
|
|
pools:new gamecore.Hashtable(), // all your pools belong to us
|
|
totalPooled:0,
|
|
totalUsed:0,
|
|
|
|
/**
|
|
* Acquire an object from a pool based on the class[name]. Typically this method is
|
|
* automatically called from
|
|
* @param classType Class of object to create
|
|
*/
|
|
acquire:function (classType)
|
|
{
|
|
var pool = this.getPool(classType);
|
|
if (pool == undefined || pool == null)
|
|
{
|
|
// create a pool for this type of class
|
|
//this.info('Constructing a new pool for ' + classType.fullName + ' objects.');
|
|
pool = new gamecore.Pool(classType, this.INITIAL_POOL_SIZE);
|
|
this.pools.put(classType.fullName, pool);
|
|
}
|
|
|
|
return pool.acquire();
|
|
},
|
|
|
|
/**
|
|
* Releases an object back into it's corresponding object pool
|
|
* @param pooledObj Object to return to the pool
|
|
*/
|
|
release:function (pooledObj)
|
|
{
|
|
var pool = this.pools.get(pooledObj.Class.fullName);
|
|
if (pool == undefined)
|
|
throw "Oops, trying to release an object of type " + pooledObj.Class.fullName +
|
|
" but no pool exists. Did you new an object instead of using create.";
|
|
|
|
pool.release(pooledObj);
|
|
},
|
|
|
|
/**
|
|
* Returns the pool associated with the given classType, or null if no pool currently exists
|
|
*/
|
|
getPool:function (classType)
|
|
{
|
|
return this.pools.get(classType.fullName);
|
|
},
|
|
|
|
getStats:function ()
|
|
{
|
|
var s = '';
|
|
|
|
var keys = this.pools.keys();
|
|
for (var i = 0; i < keys.length; i++)
|
|
{
|
|
var key = keys[i];
|
|
var pool = this.pools.get(key);
|
|
s += key + ': ' + pool.getStats() + '\n';
|
|
}
|
|
|
|
return s;
|
|
}
|
|
|
|
},
|
|
{
|
|
freeList:null,
|
|
expansion: 1,
|
|
traces: null,
|
|
|
|
/**
|
|
* Constructs a pool using a base of objects passed in as an array.
|
|
* @param classType Class name of the type of objects in the pool
|
|
* @param initial Starting number of objects in the pool
|
|
*/
|
|
init:function (classType, initial)
|
|
{
|
|
this._super();
|
|
this.classType = classType;
|
|
this.freeList = [];
|
|
|
|
// instantiate the initial objects for the pool
|
|
this.expand(initial);
|
|
},
|
|
|
|
|
|
startTracing:function ()
|
|
{
|
|
if (this.tracing) return;
|
|
this.tracing = true;
|
|
if (this.traces)
|
|
this.traces.clear();
|
|
else
|
|
this.traces = new gamecore.Hashtable();
|
|
},
|
|
|
|
stopTracing:function ()
|
|
{
|
|
this.tracing = false;
|
|
},
|
|
|
|
/**
|
|
* Expand the pool of objects by constructing a bunch of new ones. The pool will
|
|
* automatically expand itself by 10% each time it runs out of space, so generally you
|
|
* shouldn't need to use this.
|
|
* @param howMany Number of new objects you want to add
|
|
*/
|
|
expand:function (howMany)
|
|
{
|
|
gamecore.Pool.totalPooled += howMany;
|
|
|
|
//debug: if you want to track expansion
|
|
//this.debug('expanding ' + this.classType.fullName + ' by ' + howMany + ' total=' + gamecore.Pool.totalPooled);
|
|
|
|
for (var i = 0; i < howMany; i++)
|
|
this.freeList.push(new this.classType());
|
|
},
|
|
|
|
getFreeCount: function()
|
|
{
|
|
return this.freeList.length;
|
|
},
|
|
|
|
/**
|
|
* Returns the next free object by moving it from the free pool to the used
|
|
* one. If no free objects are available it returns the oldest from the used
|
|
* pool.
|
|
* access to the object
|
|
*/
|
|
acquire:function ()
|
|
{
|
|
// check if we have anymore to give out
|
|
if (this.freeList.length <= 0)
|
|
{
|
|
// create some more space (expand by 20%, minimum 1)
|
|
this.expansion = Math.round(this.expansion*1.2)+1;
|
|
this.expand(this.expansion);
|
|
}
|
|
|
|
if (this.tracing)
|
|
{
|
|
var stack = printStackTrace();
|
|
var pos = stack.length - 1;
|
|
while (stack[pos].indexOf('Class.addTo') == 0 && pos > 0)
|
|
pos--;
|
|
var count = this.traces.get(stack[pos]);
|
|
if (count == null)
|
|
this.traces.put(stack[pos], { value:1 });
|
|
else
|
|
count.value++;
|
|
}
|
|
|
|
return this.freeList.pop();
|
|
},
|
|
|
|
/**
|
|
* Releases an object by moving it from the used list back to the free list.
|
|
* @param obj {pc.Base} The obj to release back into the pool
|
|
*/
|
|
release:function (obj)
|
|
{
|
|
this.freeList.push(obj);
|
|
},
|
|
|
|
getStats:function ()
|
|
{
|
|
var s = this.Class.fullName + ' stats: ' + this.freeList.length + ' free.\n';
|
|
|
|
if (this.tracing)
|
|
{
|
|
s += 'TRACING\n';
|
|
var traceKeys = this.traces.keys();
|
|
for (var k in traceKeys)
|
|
s += traceKeys[k] + ' (' + this.traces.get(traceKeys[k]).value + ')\n';
|
|
}
|
|
return s;
|
|
},
|
|
|
|
dump:function (msg)
|
|
{
|
|
this.info('================== ' + msg + ' ===================');
|
|
this.info('FREE');
|
|
this.freeList.dump();
|
|
},
|
|
|
|
/**
|
|
* Returns the number of objects in the pool
|
|
*/
|
|
size:function ()
|
|
{
|
|
return this.freeList.length;
|
|
},
|
|
|
|
/**
|
|
* Returns the LinkedList of currently free objects in the pool
|
|
*/
|
|
getFreeList:function ()
|
|
{
|
|
return this.freeList;
|
|
}
|
|
|
|
});
|
|
|
|
/**
|
|
* @class gamecore.DualPool
|
|
* Easy (high-performance) object pooling
|
|
*
|
|
* A pool of objects for use in situations where you want to minimize object life cycling (and
|
|
* subsequently garbage collection). It also serves as a very high speed, minimal overhead
|
|
* collection for small numbers of objects.
|
|
* <p>
|
|
* This class maintains mutual set of doubly-linked lists in order to differentiate between
|
|
* objects that are in use and those that are unallocated from the pool. This allows for much
|
|
* faster cycling of only the in-use objects.
|
|
* <p>
|
|
* Pools are managed by class type, and will auto-expand as required. You can create a custom initial pool
|
|
* size by deriving from the Pool class and statically overriding INITIAL_POOL_SIZE.
|
|
* <p>
|
|
* Keep in mind that objects that are pooled are not constructed; they are "reset" when handed out.
|
|
* You need to "acquire" one and then reset its state, usually via a static create factory method.
|
|
* <p>
|
|
* Example:
|
|
* <code>
|
|
* Point = gamecore.Pooled('Point',
|
|
* {
|
|
* // Static constructor
|
|
* create:function (x, y)
|
|
* {
|
|
* var n = this._super();
|
|
* n.x = x;
|
|
* n.y = y;
|
|
* return n;
|
|
* }
|
|
* },
|
|
* {
|
|
* x:0, y:0, // instance
|
|
*
|
|
* init: function(x, y)
|
|
* {
|
|
* this.x = x;
|
|
* this.y = y;
|
|
* }
|
|
* }
|
|
* </code>
|
|
* To then access the object from the pool, use create, instead of new. Then release it.
|
|
* <code>
|
|
* var p = Point.create(100, 100);
|
|
* // ... do something
|
|
* p.release();
|
|
* </code>
|
|
*
|
|
*/
|
|
|
|
gamecore.DualPool = gamecore.Pool.extend('gamecore.DualPool',
|
|
{
|
|
acquire:function (classType)
|
|
{
|
|
var pool = this.getPool(classType);
|
|
if (pool == undefined || pool == null)
|
|
{
|
|
pool = new gamecore.DualPool(classType, this.INITIAL_POOL_SIZE);
|
|
this.pools.put(classType.fullName, pool);
|
|
}
|
|
|
|
return pool.acquire();
|
|
},
|
|
|
|
getStats:function ()
|
|
{
|
|
var s = '';
|
|
|
|
var keys = this.pools.keys();
|
|
for (var i = 0; i < keys.length; i++)
|
|
{
|
|
var key = keys[i];
|
|
var pool = this.pools.get(key);
|
|
s += key + ' (free: ' + pool.freeList.length() + ' used: ' + pool.usedList.length() + ')\n';
|
|
}
|
|
return s;
|
|
}
|
|
},
|
|
///
|
|
/// INSTANCE
|
|
///
|
|
{
|
|
freeList:null,
|
|
usedList:null,
|
|
|
|
/**
|
|
* Constructs a pool using a base of objects passed in as an array.
|
|
* @param classType Class name of the type of objects in the pool
|
|
* @param initial Starting number of objects in the pool
|
|
*/
|
|
init:function (classType, initial)
|
|
{
|
|
this.classType = classType;
|
|
this.usedList = new gamecore.LinkedList();
|
|
this.freeList = new gamecore.LinkedList();
|
|
|
|
// instantiate the initial objects for the pool
|
|
this.expand(initial);
|
|
},
|
|
|
|
/**
|
|
* Expand the pool of objects by constructing a bunch of new ones. The pool will
|
|
* automatically expand itself by 10% each time it runs out of space, so generally you
|
|
* shouldn't need to use this.
|
|
* @param howMany Number of new objects you want to add
|
|
*/
|
|
expand:function (howMany)
|
|
{
|
|
// this.info('Expanding ' + this.classType.fullName + ' pool from ' + this.size() +
|
|
// ' to ' + (this.size() + howMany) + ' objects');
|
|
gamecore.Pool.totalPooled += howMany;
|
|
for (var i = 0; i < howMany; i++)
|
|
this.freeList.add(new this.classType());
|
|
},
|
|
|
|
/**
|
|
* Returns the next free object by moving it from the free pool to the used
|
|
* one. If no free objects are available it returns the oldest from the used
|
|
* pool.
|
|
* access to the object
|
|
*/
|
|
returnObj:null,
|
|
|
|
acquire:function ()
|
|
{
|
|
// check if we have anymore to give out
|
|
if (this.freeList.first == null)
|
|
// create some more space (expand by 20%, minimum 1)
|
|
this.expand(Math.round(this.size() / 5) + 1);
|
|
|
|
this.returnObj = this.freeList.first.obj;
|
|
this.freeList.remove(this.returnObj);
|
|
this.returnObj.destroyed = false;
|
|
this.usedList.add(this.returnObj);
|
|
|
|
if (this.tracing)
|
|
{
|
|
var stack = printStackTrace();
|
|
var pos = stack.length - 1;
|
|
while (stack[pos].indexOf('Class.addTo') == 0 && pos > 0)
|
|
pos--;
|
|
var count = this.traces.get(stack[pos]);
|
|
if (count == null)
|
|
this.traces.put(stack[pos], { value:1 });
|
|
else
|
|
count.value++;
|
|
}
|
|
|
|
return this.returnObj;
|
|
},
|
|
|
|
/**
|
|
* Releases an object by moving it from the used list back to the free list.
|
|
* @param obj {pc.Base} The obj to release back into the pool
|
|
*/
|
|
release:function (obj)
|
|
{
|
|
this.freeList.add(obj);
|
|
this.usedList.remove(obj);
|
|
},
|
|
|
|
dump:function (msg)
|
|
{
|
|
this.info('================== ' + msg + ' ===================');
|
|
this.info('FREE');
|
|
this.freeList.dump();
|
|
this.info('USED');
|
|
this.usedList.dump();
|
|
},
|
|
|
|
/**
|
|
* Returns the number of objects in the pool
|
|
*/
|
|
size:function ()
|
|
{
|
|
return this.freeList.count + this.usedList.count;
|
|
},
|
|
|
|
/**
|
|
* Returns the LinkedList of current used objects in the pool
|
|
* @return {*}
|
|
*/
|
|
getUsedList:function ()
|
|
{
|
|
return this.usedList;
|
|
}
|
|
});
|
|
|
|
|
|
/**
|
|
* @class gamecore.Pooled
|
|
* Used as a base class for objects which are life cycle managed in an object pool.
|
|
*/
|
|
gamecore.Pooled = gamecore.Base('gamecore.Pooled',
|
|
///
|
|
/// STATICS
|
|
///
|
|
{
|
|
/**
|
|
* Static factory method for creating a new object based on its class. This method
|
|
* should be called using this._super from the Class.create that derives from this.
|
|
* @returns An object from the pool
|
|
*/
|
|
create:function ()
|
|
{
|
|
return gamecore.Pool.acquire(this);
|
|
},
|
|
|
|
getPool:function ()
|
|
{
|
|
return gamecore.Pool.getPool(this);
|
|
}
|
|
|
|
},
|
|
///
|
|
/// INSTANCE
|
|
///
|
|
{
|
|
destroyed:false,
|
|
|
|
init:function ()
|
|
{
|
|
this._super();
|
|
},
|
|
|
|
release:function ()
|
|
{
|
|
this.onRelease();
|
|
gamecore.Pool.release(this);
|
|
},
|
|
|
|
onRelease:function ()
|
|
{
|
|
}
|
|
|
|
});
|
|
|
|
|
|
/**
|
|
* @class gamecore.DualPooled
|
|
* Used as a base class for objects which are life cycle managed in an object pool (the DualPool edition)
|
|
*/
|
|
gamecore.DualPooled = gamecore.Base('gamecore.DualPooled',
|
|
///
|
|
/// STATICS
|
|
///
|
|
{
|
|
/**
|
|
* Static factory method for creating a new object based on its class. This method
|
|
* should be called using this._super from the Class.create that derives from this.
|
|
* @returns An object from the pool
|
|
*/
|
|
create:function ()
|
|
{
|
|
return gamecore.DualPool.acquire(this);
|
|
},
|
|
|
|
getPool:function ()
|
|
{
|
|
return gamecore.DualPool.getPool(this);
|
|
}
|
|
|
|
},
|
|
///
|
|
/// INSTANCE
|
|
///
|
|
{
|
|
destroyed:false,
|
|
|
|
init:function ()
|
|
{
|
|
this._super();
|
|
},
|
|
|
|
release:function ()
|
|
{
|
|
this.onRelease();
|
|
gamecore.DualPool.release(this);
|
|
},
|
|
|
|
onRelease:function ()
|
|
{
|
|
}
|
|
|
|
});
|