451 lines
12 KiB
JavaScript
451 lines
12 KiB
JavaScript
/* **** CBDL - Cross-browser DirectMedia Layer
|
|
*
|
|
* look at: http://en.wikipedia.org/wiki/SFML
|
|
*/
|
|
var CBDL = CBDL || {};
|
|
|
|
CBDL.version = 0.1;
|
|
|
|
CBDL.dump = function() {
|
|
console.log("CBDL version "+CBDL.version);
|
|
}
|
|
|
|
/*
|
|
===============================================================================
|
|
|
|
CBDL.Includes
|
|
|
|
Object that manages includes for an App. Attempts to load all includes
|
|
specified by the App, providing they are provided prior to the App's onExecute
|
|
member function being called.
|
|
===============================================================================
|
|
*/
|
|
CBDL.Includes = function(app) {
|
|
_Includes = this;
|
|
this.app = app;
|
|
this.state = 0x00;
|
|
this.current = 0;
|
|
this.includes = [];
|
|
|
|
this.add = function(some_library) {
|
|
if (this.state != CBDL.states.LOADED) {
|
|
this.includes.push(some_library);
|
|
if (this.state != CBDL.states.LOADING) {
|
|
this.load();
|
|
}
|
|
}
|
|
};
|
|
|
|
this.load = function() {
|
|
this.state = CBDL.states.LOADING;
|
|
if (this.current < this.includes.length) {
|
|
this.netLoad();
|
|
} else {
|
|
this.state = CBDL.states.LOADED;
|
|
this.app.includeCallback();
|
|
}
|
|
};
|
|
|
|
this.netLoad = function() {
|
|
var element = document.createElement("script");
|
|
element.type = "text/javascript";
|
|
element.src = _Includes.includes[_Includes.current];
|
|
element.onload = function() {
|
|
_Includes.state = 0x00;
|
|
_Includes.current++;
|
|
_Includes.load(); // load next file
|
|
}
|
|
document.getElementsByTagName('head')[0].appendChild(element);
|
|
// if (!/*@cc_on!@*/false) {
|
|
/* var request = new XMLHttpRequest();
|
|
} else {
|
|
var request = new ActiveXObject("Microsoft.XMLHTTP");
|
|
}
|
|
request.onreadystatechange = function() {
|
|
if (this.readyState == 4) { // done loading
|
|
console.log(this.status);
|
|
if (this.status == 200) {
|
|
var element = document.createElement("script");
|
|
element.type = "text/javascript";
|
|
element.text = this.responseText;
|
|
document.getElementsByTagName('head')[0].appendChild(element);
|
|
_Includes.state = 0x00;
|
|
_Includes.current++;
|
|
_Includes.load(); // load next file
|
|
} else {
|
|
_Includes.state = CBDL.states.FAILED;
|
|
}
|
|
}
|
|
}
|
|
request.open('GET', _Includes.includes[_Includes.current], true);
|
|
request.send(null);
|
|
*/
|
|
};
|
|
|
|
}
|
|
|
|
/*
|
|
===============================================================================
|
|
|
|
CBDL.App
|
|
|
|
Object that should be the base for all CBDL-based applications. Contains the
|
|
bare-minimum logic, members, and vars that any CBDL app should hold.
|
|
|
|
Usage:
|
|
some_app = new CBDL.App();
|
|
some_app.Init();
|
|
|
|
===============================================================================
|
|
*/
|
|
CBDL.App = CBDL.App || function() {};
|
|
|
|
CBDL.App.prototype.Main = function() {};
|
|
CBDL.App.prototype.Go = function() {
|
|
if (this.requires) {
|
|
this._includes = new CBDL.Includes(this);
|
|
for (var require in this.requires) {
|
|
this._includes.add(this.requires[require]);
|
|
}
|
|
}
|
|
if (this._includes) {
|
|
if (this._includes.state != CBDL.states.LOADED) {
|
|
this.includeCallback = function(return_value) {
|
|
if (return_value < 0) { // fail
|
|
console.log("CBDL error: includes failed to load!");
|
|
return return_value;
|
|
}
|
|
this.Main();
|
|
};
|
|
} else if (this._includes.state == CBDL.states.LOADED) {
|
|
this.Main();
|
|
}
|
|
} else {
|
|
this.Main();
|
|
}
|
|
};
|
|
CBDL.App.prototype.include = function(some_library) {
|
|
if (!this._includes) {
|
|
this._includes = new CBDL.Includes(this);
|
|
}
|
|
this._includes.add(some_library);
|
|
};
|
|
/* called when all includes succeed or fail */
|
|
CBDL.App.prototype.includeCallback = function(return_value) {
|
|
if (return_value < 0) { // fail
|
|
console.log("CBDL error: includes failed to load!");
|
|
return return_value;
|
|
} else {
|
|
this.Main();
|
|
}
|
|
};
|
|
|
|
/*
|
|
================
|
|
CBDL.inherit(baseClass, newClass)
|
|
|
|
Function that inherits the properties from baseClass into newClass
|
|
================
|
|
*/
|
|
CBDL.inherit = function(base_class, new_class) {
|
|
base_class.call(new_class);
|
|
new_class.constructor = new_class;
|
|
}
|
|
CBDL.inherits = function(base_class, new_class) {
|
|
new_class.prototype = new base_class;
|
|
new_class.prototype.constructor = base_class; // fix constructor
|
|
}
|
|
|
|
CBDL.extends = function(base_class, new_class) {
|
|
new_class.prototype = new base_class;
|
|
new_class.prototype.constructor = base_class; // fix constructor
|
|
}
|
|
|
|
|
|
/*
|
|
================
|
|
CBDL.startApp(function)
|
|
|
|
Function which is used to start the CBDL-based application that is passed
|
|
as its argument. The application, being an Object, requires, at bare minimum,
|
|
onInit(), onExecute(), and onLoop() member functions. This function then calls
|
|
onInit(), and if all goes well, to call onExecute().
|
|
What this effectively accomplishes is header/defines in the onInit, and a
|
|
base main() call in the onExecute().
|
|
|
|
Usage:
|
|
someApp = function() {
|
|
this.onInit = function() {
|
|
include("some_library.js");
|
|
};
|
|
this.onExecute = function() {
|
|
console.log("some_app executed!");
|
|
};
|
|
}
|
|
CBDL.startApp(new someApp);
|
|
================
|
|
*/
|
|
CBDL.startApp = function(app) {
|
|
if (!app.onInit || !app.onExecute) {
|
|
console.log("CBDL error: missing onInit or onExecute app member!");
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
/*
|
|
===============================================================================
|
|
|
|
CBDL.Loop(callback, interval)
|
|
|
|
Object that acts as a simple interface to creating and managing loops within
|
|
the script. Attempts to call callback() after X interval has passed. Interval
|
|
is modified internally to adjust for the time callback() takes to finish. If
|
|
the time is beyond the defined interval, then callback() is called with a 0ms
|
|
delay.
|
|
If the interval is not passed, or is passed as 0, then the Loop will rely
|
|
on the callback() to return an interval value.
|
|
|
|
Usage:
|
|
new_loop = new CBDL.Loop(some_func, 50);
|
|
new_loop.start(50); // calls some_func() after 50ms and repeats every 50ms.
|
|
Or:
|
|
some_func = function() { return(1000); };
|
|
new_loop = new CBDL.Loop(some_func);
|
|
new_loop.start(); // calls some_func() every 1000ms.
|
|
|
|
===============================================================================
|
|
*/
|
|
CBDL.Loop = function(callback, interval) {
|
|
_Loop = this;
|
|
this.callback = callback;
|
|
this.interval = (interval ? interval : 0);
|
|
|
|
this.time_start = 0;
|
|
this.time_end = 0;
|
|
this.time_delay = this.interval;
|
|
|
|
this.running = false;
|
|
this.start = function(delay) {
|
|
this.running = true;
|
|
|
|
if (delay) {
|
|
setTimeout(function() { _Loop.loop(); }, delay);
|
|
} else {
|
|
this.loop();
|
|
}
|
|
};
|
|
this.stop = function() {
|
|
this.running = false;
|
|
};
|
|
this.loop = function() {
|
|
if (this.running) {
|
|
if (this.interval == 0) { // acquire time_delay from callback return
|
|
this.time_delay = this.callback();
|
|
} else {
|
|
this.time_start = new Date().getTime();
|
|
this.callback(this.time_start-this.time_end); // return delta to callback
|
|
this.time_end = new Date().getTime();
|
|
this.time_delay = this.time_end-this.time_start;
|
|
this.time_delay = (this.time_delay > this.interval ? 0 : this.interval - this.time_delay);
|
|
}
|
|
setTimeout(function() { _Loop.loop(); }, this.time_delay);
|
|
}
|
|
};
|
|
}
|
|
|
|
/*
|
|
================
|
|
CBDL.newLoop(callback, interval)
|
|
|
|
Creates and returns a new Loop object. Once the Loop's start member is
|
|
called, CBDL continually calls the callback at the specified interval
|
|
times.
|
|
|
|
Usage:
|
|
new_loop = CBDL.newLoop(function() { console.log("test"); }, 500);
|
|
new_loop.start(); // begins printing "test" to the console every 500ms
|
|
================
|
|
*/
|
|
CBDL.newLoop = function(callback, interval) {
|
|
if (callback instanceof Object) {
|
|
return new CBDL.Loop(callback, interval);
|
|
}
|
|
}
|
|
|
|
/*
|
|
================
|
|
CBDL.useNamespace(object)
|
|
|
|
Sets the window parent to own all of the defined object's members. Functions
|
|
in a fashion similar to setting the namespace in C++.
|
|
|
|
Usage:
|
|
CBDL.dump(); // prints CBDL version
|
|
CBDL.useNamespace(CBDL);
|
|
dump(); // prints CBDL version
|
|
================
|
|
*/
|
|
CBDL.useNamespace = function(object) {
|
|
var parent = window;
|
|
for (var member in object) {
|
|
parent[member] = object[member];
|
|
}
|
|
}
|
|
/*
|
|
================
|
|
CBDL.globalize(name, variable)
|
|
|
|
Adds the passed variable/function/object to a new var in the "global"
|
|
namespace via the passed name.
|
|
|
|
Usage:
|
|
some_function() {
|
|
var foo = 'bar';
|
|
}
|
|
console.log(foo); // undefined
|
|
some_function() {
|
|
var foo = 'bar';
|
|
CBDL.globalize("foo", foo); // window.foo = 'bar', effectively
|
|
}
|
|
console.log(foo); // prints 'bar'
|
|
================
|
|
*/
|
|
CBDL.globalize = function(name, variable) {
|
|
var parent = window;
|
|
parent[name] = parent[name] || variable;
|
|
}
|
|
|
|
/*
|
|
===============================================================================
|
|
|
|
CBDL.Include(filename)
|
|
|
|
Internal object created by calls to CBDL.include(filename). Simply stores the
|
|
filename and the current state via the 'state' member (bitmask).
|
|
|
|
===============================================================================
|
|
*/
|
|
|
|
CBDL.Include = function(filename) {
|
|
this.filename = filename;
|
|
this.state = 0x00;
|
|
}
|
|
|
|
CBDL.current_include = 0;
|
|
CBDL.includes = [];
|
|
|
|
CBDL.states = {OPEN: 0x00, LOADING:0x01, LOADED:0x02, FAILED:0x03};
|
|
|
|
/*
|
|
================
|
|
CBDL.include(filename)
|
|
|
|
Method which should be invoked by the program implementing CBDL. It provides
|
|
a nice method for including new source files/libraries located within the same
|
|
directory as the invoking script.
|
|
|
|
Usage:
|
|
CBDL.include("CBDL_video.js"); // loads CBDL_video.js, making all objects/vars,
|
|
etc. available to the calling script.
|
|
|
|
================
|
|
*/
|
|
CBDL.include = function(filename) {
|
|
if (typeof filename == "string") {
|
|
CBDL.includes.push(new CBDL.Include(filename));
|
|
if (CBDL.includes[CBDL.current_include].state === CBDL.states.OPEN) {
|
|
CBDL.loadInclude(CBDL.includes[CBDL.current_include]);
|
|
//CBDL.nextInclude();
|
|
}
|
|
} else {
|
|
for (var file in filename) {
|
|
CBDL.include(filename[file]);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
================
|
|
CBDL.nextInclude()
|
|
|
|
Internal method that is called when an Include finishes loading, so as to
|
|
load the next Include within the includes list.
|
|
|
|
Usage:
|
|
CBDL.nextInclude();
|
|
|
|
================
|
|
*/
|
|
CBDL.nextInclude = function() {
|
|
if (CBDL.includes[CBDL.current_include+1] instanceof CBDL.Include) {
|
|
CBDL.current_include++;
|
|
CBDL.loadInclude(CBDL.includes[CBDL.current_include]);
|
|
} else {
|
|
// CBDL.onReady();
|
|
// CBDL.onReady = function(){};
|
|
}
|
|
}
|
|
|
|
/*
|
|
================
|
|
CBDL.loadInclude(Include)
|
|
|
|
Internal method that attempts to use XMLHttpRequest or otherwise to
|
|
dynamically load the specified Include. Upon success, a new <script> is
|
|
added to the page's <head> and the state of the Include is changed to LOADED.
|
|
|
|
Usage:
|
|
new_include = new CBDL.Include("CBDL_net.js");
|
|
CBDL.loadInclude(new_include);
|
|
console.log("state is: " + new_include.state);
|
|
================
|
|
*/
|
|
CBDL.loadInclude = function(include) {
|
|
var element = document.createElement("script");
|
|
element.type = "text/javascript";
|
|
element.src = include.filename;
|
|
element.onload = function() {
|
|
include.state = CBDL.states.LOADED;
|
|
CBDL.nextInclude();
|
|
}
|
|
document.getElementsByTagName('head')[0].appendChild(element);
|
|
|
|
// if (!/*@cc_on!@*/false) {
|
|
/* var request = new XMLHttpRequest();
|
|
} else {
|
|
var request = new ActiveXObject("Microsoft.XMLHTTP");
|
|
}
|
|
request.onreadystatechange = function() {
|
|
if (this.readyState == 4) { // done loading
|
|
if (this.status == 200) {
|
|
include.element = document.createElement("script");
|
|
include.element.type = "text/javascript";
|
|
include.element.text = this.responseText;
|
|
document.getElementsByTagName('head')[0].appendChild(include.element);
|
|
include.state = CBDL.states.LOADED;
|
|
} else {
|
|
include.state = CBDL.states.FAILED;
|
|
}
|
|
CBDL.nextInclude();
|
|
} else if (this.readyState == 2) { // loading
|
|
include.state = CBDL.states.LOADING;
|
|
}
|
|
}
|
|
request.open('GET', include.filename, true);
|
|
request.send(null);
|
|
*/
|
|
}
|
|
|
|
/* Event object which is used to poll a variety of events, as defined through
|
|
* the passed event_masks bitmask, or by calling Event's addEvent method.
|
|
*/
|
|
CBDL.Event = function(event_masks) {
|
|
this.pollEvents = function() {
|
|
if (event_pool.isEmpty()) {
|
|
return -1;
|
|
} else {
|
|
return event_pool.getNext();
|
|
}
|
|
}
|
|
}
|