Added base CBDL files. At the moment, CBDL.Loop is broken and CBDL.Includes are hacked - to be fixed, but initial commits are important!

HEAD
kts 2013-03-14 23:11:30 -07:00
commit 2820319212
5 changed files with 673 additions and 0 deletions

450
CBDL.js 100644
View File

@ -0,0 +1,450 @@
/* **** 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();
}
}
}

32
CBDL_events.js 100644
View File

@ -0,0 +1,32 @@
/* **** CBDL_net - Optional layer which adds network support
*
*
* */
CBDL.Events = CBDL.Events || {};
CBDL.Events.version = 0.1;
/*
================
CBDL.Event = CBDL.Event || CBDL.Events.Event;
================
*/
/*
===============================================================================
CBDL.Events.Event
Event object that should be instantized with a flag mask specifying the
events to listen for. Events should be iterated through by running the Event's
Poll() function.
===============================================================================
*/
CBDL.Events.Event = function(events_flag, max_events) {
var position; // Our current position in the events list.
this.Poll = function() {
position++;
};
};

151
CBDL_graphics.js 100644
View File

@ -0,0 +1,151 @@
CBDL.include("excanvas.js");
/* **** CBDL_net - Optional layer which adds network support
*
*
* */
CBDL.Graphics = CBDL.Graphics || {};
CBDL.Graphics.version = 0.1;
CBDL.Graphics.DisplayType = {DIV: 0x00, CANVAS_2D:0x01};
CBDL.Graphics.backends = {DIV: 0x00, CANVAS_2D:0x01};
/*
===============================================================================
CBDL.Graphics.DisplaySkeleton
Basic Display skeleton from which all Display backends should be derived
from. It is through the backend detection that the Display backend, being named
something similar to Html5Display, is assigned as Graphics.Display. This allows
for backends to be used/sent according to browser capability, rather than via
bulk.
===============================================================================
*/
CBDL.Graphics.DisplaySkeleton = function(video_mode, target_element) {
};
CBDL.Graphics.DisplaySkeleton.prototype.Init = function() {
};
CBDL.Graphics.DisplaySkeleton.prototype.Fill = function(red, green, blue) {
};
/*
===============================================================================
CBDL.Graphics.Display
Base window onto which various Graphics elements can be placed within.
Effectively exists as a simple wrapper to a 'div' element. The first parameter
passed is an instance of a VideoMode(width, height). The second optional
parameter is a target HTML element. If ommitted, the Display adds its element
to document.body.
Usage:
===============================================================================
*/
CBDL.Graphics.Display = function(video_mode, target_element) {
var _context = CBDL.Graphics;
this.context = null;
this.init = function() {
try { this.element = document.createElement("canvas"); }
catch (x) { this.element = null; }
if (this.element == null) { // fallback to nasty divs
this.element = document.createElement("div");
this.element.style.width = this.videomode.width;
this.element.style.height = this.videomode.height;
this.element.style.backgroundColor = 'black';
this.element.style.display = "block";
this.type = _context.DisplayType.DIV;
} else { // using HTML5 canvas
if (typeof G_vmlCanvasManager != "undefined") { // IE8, bleh
G_vmlCanvasManager.initElement(this.element);
}
this.type = _context.DisplayType.CANVAS_2D;
this.element.style.width = this.videomode.width;
this.element.style.height = this.videomode.height;
try { this.context = this.element.getContext("2d"); }
catch (x) { this.context = null; }
if (this.context == null) {
} else {
this.context.fillStyle = "#000000";
this.context.fillRect(0, 0, this.videomode.width, this.videomode.height);
}
}
(target_element ? target_element : document.body).appendChild(this.element);
};
this.Fill = function(red, green, blue) {
var hex_value = ((1 << 24) + (red << 16) + (green << 8) + blue);
var hex_string = hex_value.toString(16).substr(1);
if (this.type == _context.DisplayType.DIV) {
this.element.style.backgroundColor = '#'+hex_string;
} else if (this.type == _context.DisplayType.CANVAS_2D) {
//this.context.fillStyle = "#"+hex_string;
//this.context.fillRect(0, 0, this.videomode.width, this.videomode.height);
}
};
if (video_mode instanceof CBDL.Graphics.VideoMode) {
this.videomode = video_mode;
this.init();
}
}
/*
===============================================================================
CBDL.Graphics.VideoMode(width, height);
Object which should be passed as the first parameter to Graphics.Display,
defining the width and height of the Display.
===============================================================================
*/
CBDL.Graphics.VideoMode = function(width, height) {
this.width = width;
this.height = height;
}
/*
===============================================================================
CBDL.Graphics.Drawable(2dVector position, 2dVector scale, float rotation)
Base class for all objects that can be drawn to a Graphics.Display.
Usage:
===============================================================================
*/
CBDL.Graphics.Drawable = function(position, scale, rotation) {
this.setPosition = function(x, y) {
}
this.setScale = function(x, y) {
}
this.setCenter = function(x, y) {
}
this.setRotation = function(rotation) {
}
}
/*
===============================================================================
===============================================================================
*/
CBDL._Graphics_ = function() {};
CBDL._Graphics_.prototype.VideoMode = function(width, height) {
this.width = width;
this.height = height;
};

6
CBDL_net.js 100644
View File

@ -0,0 +1,6 @@
/* **** CBDL_net - Optional layer which adds network support
*
*
* */
CBDL.Net = CBDL.Net || {};
CBDL.Net.version = 0.1;

34
cbdl.html 100644
View File

@ -0,0 +1,34 @@
<html>
<head>
<script type="text/javascript" src="CBDL.js"></script>
<script type="text/javascript">
myApp = function() {
this.requires = ["CBDL_graphics.js"];
var main_display; // private member
var main_loop; // private member
this.Main = function() { // override parent's Main
console.log("bleh");
main_display = new CBDL.Graphics.Display(new CBDL.Graphics.VideoMode(800, 600));
(main_loop = new CBDL.Loop(this.Loop)).start();
};
this.Loop = function(delta) { // our custom Loop member :)
main_display.Fill(0xFF, 0xF0, 0xF0);
console.log(main_loop.time_delay+", delta: "+delta);
return(1000);
};
}; CBDL.extends(CBDL.App, myApp); // Don't forget this line! sets up prototypal inheritance
init = function() {
var app = new myApp();
app.Go();
}
</script>
</head>
<body>
<button onclick="init()">init()</button>
</body>
</html>