BrokenFinger: Irrlicht + SpiderMonkey

Discussion about everything. New games, 3d math, development tips...
Post Reply
dlangdev
Posts: 1324
Joined: Tue Aug 07, 2007 7:28 pm
Location: Beaverton OR
Contact:

BrokenFinger: Irrlicht + SpiderMonkey

Post by dlangdev »

Hi All,

First, I'd like to know if there's anybody working on a SpiderMonkey binding to Irrlicht. I'd like to get their attention and give me some advice.

Secondly, I've started writing the Spidermonkey binding for a 3D application named: BrokenFinger.

BrokenFinger, what is it?

Basically, a simple application that blends the following into a single application: Irrlicht, Spidermonkey and XML.

The result is an application having a Document Object Model, accessible by means of scripting.

In this I can do the following:
1) launch a console window inside the app window.
2) type javascript code.
3) submit it to the interpreter.
4) interpreter executes the script against the irrlicht runtime.

In short, i can:
1) query the object model and receive the current state of the runtime.
2) modify object states by submitting scripts against the runtime.

I'm going to post the initial code I made to test two Irrlicht classes.

What I'd like to know is:
1) Am I doing something that's already been done. Let me know where I can get in touch.
2) If there's anybody willing to contribute their precious time getting the SpiderMonkey binding moving.

Thanks, the code will be posted right after this message. Scroll down to the next and you'll see the code.
Last edited by dlangdev on Sun Dec 02, 2007 6:59 am, edited 1 time in total.
dlangdev
Posts: 1324
Joined: Tue Aug 07, 2007 7:28 pm
Location: Beaverton OR
Contact:

Post by dlangdev »

Code: Select all


//
// Project: Broken Finger
//
//
// main.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

/* SpiderMonkey API declarations */
#include <jsapi.h>

/* Irrlicht */
#include <irrlicht.h>

/* C++ */
#include <iostream>
#include <stdlib.h>  
#include <string.h>

using namespace irr;

#pragma comment(lib, "Irrlicht.lib")

//--------------------------------------------------------------------------------
// Globals
//
IrrlichtDevice* device;

//--------------------------------------------------------------------------------
// Javascript Print Error
//
void
printError(JSContext *cx, const char *message, JSErrorReport *report)
{
  int where;
  char* cstr;
  
  fprintf(stderr, "JSERROR: %s:%d:\n    %s\n",
	  (report->filename ? report->filename : "NULL"),
	  report->lineno,
	  message);
  if (report->linebuf) {
    fprintf(stderr, "    \"%s\"\n",cstr);
    free(cstr);
    if (report->tokenptr) {
      where=report->tokenptr - report->linebuf;
      /* Todo: 80 */
      if ((where>=0)&&(where<80)) {
	where+=6;
	while (--where>0) fputc(' ',stderr);
	fprintf(stderr, "^\n");
      }
    }
  }
  fprintf(stderr, "    Flags:");
  if (JSREPORT_IS_WARNING(report->flags)) fprintf(stderr, " WARNING");
  if (JSREPORT_IS_EXCEPTION(report->flags)) fprintf(stderr, " EXCEPTION");
  if (JSREPORT_IS_STRICT(report->flags)) fprintf(stderr, " STRICT");
  fprintf(stderr, " (Error number: %d)\n", report->errorNumber);
}
//--------------------------------------------------------------------------------
//  Scene Node Object
//
static JSBool
addSceneNode(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
	std::cout << "\n\n1.0 Inside addSceneNode: " << " \n\n";
	return JS_TRUE;
}
static JSBool
loadScene(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
	std::cout << "\n\n1.0 Inside loadScene: " << " \n\n";
	return JS_TRUE;
}
static JSBool
saveScene(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
	std::cout << "\n\n1.0 Inside saveScene: " << " \n\n";
	return JS_TRUE;
}
static JSBool
createNewSceneManager(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
	std::cout << "\n\n1.0 Inside createNewSceneManager: " << " \n\n";
	return JS_TRUE;
}
static JSBool
getSceneNodeTypeName(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
	std::cout << "\n\n1.0 Inside getSceneNodeTypeName: " << " \n\n";
	return JS_TRUE;
}
static JSBool
getSceneNodeAnimatorFactory(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
	std::cout << "\n\n1.0 Inside getSceneNodeAnimatorFactory: " << " \n\n";
	return JS_TRUE;
}
static JSBool
getRegisteredSceneNodeAnimatorFactoryCount(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
	std::cout << "\n\n1.0 Inside getRegisteredSceneNodeAnimatorFactoryCount: " << " \n\n";
	return JS_TRUE;
}
static JSBool
createTerrainTriangleSelector(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
	std::cout << "\n\n1.0 Inside createTerrainTriangleSelector: " << " \n\n";
	return JS_TRUE;
}
static JSBool
createOctTreeTriangleSelector(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
	std::cout << "\n\n1.0 Inside createOctTreeTriangleSelector: " << " \n\n";
	return JS_TRUE;
}

JSClass sceneManagerClass = {
    "sceneManager", JSCLASS_HAS_PRIVATE,
    JS_PropertyStub,  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
    JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,  JS_FinalizeStub
};

static JSFunctionSpec sceneManagerMethods[] = {
	{"addSceneNode",					(JSNative)addSceneNode,		0,0,0},
	{"loadScene",						(JSNative)loadScene,		0,0,0},
	{"saveScene",						(JSNative)saveScene,		0,0,0},
	{"createNewSceneManager",			(JSNative)createNewSceneManager,	0,0,0},
	{"getSceneNodeTypeName",			(JSNative)getSceneNodeTypeName,		0,0,0},
	{"getSceneNodeAnimatorFactory",		(JSNative)getSceneNodeAnimatorFactory,		0,0,0},
	{"getRegisteredSceneNodeAnimatorFactoryCount",	(JSNative)getRegisteredSceneNodeAnimatorFactoryCount,		0,0,0},
	{"createTerrainTriangleSelector",	(JSNative)createTerrainTriangleSelector,		0,0,0},
	{"createOctTreeTriangleSelector",	(JSNative)createOctTreeTriangleSelector,		0,0,0},
	
    {NULL, NULL, 0,0,0}
};

//--------------------------------------------------------------------------------
//  Irrlicht Class
//
static JSBool
IrrlichtGetProperty(JSContext *cx, JSObject *obj, jsval name, jsval *rval)
{
    char *last = JS_GetStringBytes(JS_ValueToString(cx, name)), *path, package[256];

	std::cout << "\n1.0 IrrlichtGetProperty: " << last << " \n";

    char *args[] = {NULL, NULL};
    char *predefined_methods[] = {"path", "toString", "getSceneManager", "getVideoDriver", "getFileSystem", "getGUIEnvironment"};
    int count;
    jsval v;
    int i;

    for(i=0;i<sizeof(predefined_methods)/sizeof(char*);i++){
		std::cout << "\n2.0 predefined_methods[" << i << "]" << predefined_methods[i] << " == " << last << "\n";
        if(!strcmp(predefined_methods[i], last)){
			std::cout << "\n2.0 IrrlichtGetProperty: native property found. exiting. \n\na";
            return JS_TRUE;
        }
    }
	std::cout << "\n3.0 IrrlichtGetProperty\n";

    return JS_TRUE;
}

static JSBool
IrrlichtGetProperty2(JSContext *cx, JSObject *obj, jsval name, jsval *rval)
{

}

JSClass irrlichtClass = {
    "irrlicht", JSCLASS_HAS_PRIVATE,
    JS_PropertyStub,  JS_PropertyStub, /*JS_PropertyStub*/IrrlichtGetProperty, JS_PropertyStub,
    JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,  JS_FinalizeStub
};

static JSBool
getSceneManager(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
	std::cout << "\n\nInside getSceneManager\n";

    JSObject *anObject;
    anObject = JS_NewObject(cx, &sceneManagerClass, NULL, NULL);
    if(!anObject)
        return JS_FALSE;
    if(!JS_DefineFunctions(cx, anObject, sceneManagerMethods))
        return JS_FALSE;
    JS_SetPrivate(cx, anObject, device);
    *rval = OBJECT_TO_JSVAL(anObject);

	return JS_TRUE;
}
static JSBool
getVideoDriver(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
	*rval = OBJECT_TO_JSVAL(device->getVideoDriver());
	return JS_TRUE;
}
static JSBool
getFileSystem(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
	*rval = OBJECT_TO_JSVAL(device->getFileSystem());
	return JS_TRUE;
}
static JSBool
getGUIEnvironment(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
	*rval = OBJECT_TO_JSVAL(device->getGUIEnvironment());
	return JS_TRUE;
}
static JSBool
getCursorControl(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
	*rval = OBJECT_TO_JSVAL(device->getCursorControl());
	return JS_TRUE;
}
static JSBool
getLogger(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
	*rval = OBJECT_TO_JSVAL(device->getLogger());
	return JS_TRUE;
}
static JSBool
IrrlichtToString(JSContext *cx, JSObject *obj, int argc, jsval *argv, jsval* rval){
	std::cout << "In IrrlichtToString\n";
    JSString *imported = JS_NewStringCopyZ(cx, "Irrlicht::");;
    if (!imported)
        return JS_FALSE;
    *rval = STRING_TO_JSVAL(imported);
	std::cout << "Exiting IrrlichtToString\n";
    return JS_TRUE;
}
static JSFunctionSpec irrlichtMethods[] = {
	{"toString",			(JSNative)IrrlichtToString,		0,0,0},
    {"getSceneManager",		(JSNative)getSceneManager,		0,0,0},
    {"getVideoDriver",		(JSNative)getVideoDriver,		0,0,0},
    {"getFileSystem",		(JSNative)getFileSystem,		0,0,0},
    {"getGUIEnvironment",	(JSNative)getGUIEnvironment,	0,0,0},
    {"getCursorControl",	(JSNative)getCursorControl,     0,0,0},
    {"getLogger",			(JSNative)getLogger,			0,0,0},
    {NULL, NULL, 0,0,0}
};

    enum irrlichtPropertiesID {
        MY_NAME, MY_PATH
    };
	static JSPropertySpec irrlichtProperties[] = {
    {"name",        MY_NAME,        JSPROP_ENUMERATE},
    {"path",        MY_PATH,		JSPROP_ENUMERATE},
    {0}
};

static JSBool
IrrlichtConstruct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *v)
{
    JSBool ok;
	ok = JS_TRUE;
	std::cout << "Inside IrrlichtConstruct...new instance created\n";

    JSObject *irrObject;
    irrObject = JS_NewObject(cx, &irrlichtClass, NULL, NULL);
    if(!irrObject)
        return JS_FALSE;
    if(!JS_DefineFunctions(cx, irrObject, irrlichtMethods))
        return JS_FALSE;
    JS_SetPrivate(cx, irrObject, device);
    *v = OBJECT_TO_JSVAL(irrObject);

	return ok;
}


static JSObject*
JS_InitIrrlichtClass(JSContext *cx, JSObject *obj)
{
    jsval v;
    JSObject *module;
    JSString *mainString = JS_NewStringCopyZ(cx, "main");
    if (!mainString)
        return NULL;
    v = STRING_TO_JSVAL(mainString);
    module = JS_NewObject(cx, &irrlichtClass, NULL, obj);
    if (!module)
        return NULL;

    if (!JS_DefineFunctions(cx, module, irrlichtMethods))
        return NULL;

    //JS_SetProperty(cx, module, "path", &v);
	JS_DefineProperties(cx, module, irrlichtProperties);

	std::cout << "JS_InitIrrlichtClass...initializing\n";

    return JS_InitClass(cx, obj, module, &irrlichtClass, 
		/* native constructor function and min arg count */
		IrrlichtConstruct, 0,
        /* prototype object properties and methods -- these
           will be "inherited" by all instances through
           delegation up the instance's prototype link. */
        NULL, NULL, 
		/* class constructor properties and methods */
		NULL, NULL);
}

//--------------------------------------------------------------------------------


int _tmain(int argc, _TCHAR* argv[])
{

  /* pointer to our runtime object */
  JSRuntime *runtime=NULL;
  /* pointer to our context */
  JSContext *context=NULL;
  /* pointer to our global JavaScript object */
  JSObject  *global=NULL;

  /* script to run (should return 100) */
  char *script="var x=10;x*x;\nvar irr=irrlicht();\nvar scmgr=irr.getSceneManager();\nvar node=scmgr.addSceneNode();\n";
  std::cout << "\nscript:" << script << "\n\n";
  /* JavaScript value to store the result of the script */
  jsval rval;
  
  /* create new runtime, new context, global object */
  if (    (!(runtime = JS_NewRuntime (1024L*1024L)))
       || (!(context = JS_NewContext (runtime, 8192)))
       || (!(global  = JS_NewObject  (context, NULL, NULL, NULL)))
     ) 
  {
	  return EXIT_FAILURE;
  }
  /* set global object of context and initialize standard ECMAScript
     objects (Math, Date, ...) within this global object scope */
  if (!JS_InitStandardClasses(context, global)) return EXIT_FAILURE;


  std::cout << "\n\Javascript: ncalling JS_InitIrrlichtClass\n";
	JS_InitIrrlichtClass(context, global);

	/* register error handler */
	JS_SetErrorReporter(context, printError);

	video::E_DRIVER_TYPE driverType;

	printf("Please select the driver you want for this example:\n"\
		" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
		" (d) Software Renderer\n (e) Burning's Software Renderer\n"\
		" (f) NullDevice\n (otherKey) exit\n\n");

	char i;
	std::cin >> i;

	switch(i)
	{
		case 'a': driverType = video::EDT_DIRECT3D9;break;
		case 'b': driverType = video::EDT_DIRECT3D8;break;
		case 'c': driverType = video::EDT_OPENGL;   break;
		case 'd': driverType = video::EDT_SOFTWARE; break;
		case 'e': driverType = video::EDT_BURNINGSVIDEO;break;
		case 'f': driverType = video::EDT_NULL;     break;
		default: return 1;
	}	


	// create device and exit if creation failed

	device = createDevice(driverType, core::dimension2d<s32>(300, 200));

	if (device == 0)
		return 1; // could not create selected driver.

	//JS_AddNamedRoot(context,device,"irrdevice");



	device->setWindowCaption(L"Load .irr file example");

	video::IVideoDriver* driver = device->getVideoDriver();
	scene::ISceneManager* smgr = device->getSceneManager();


	// load the scene
	std::cout << "loadScene\n";
	smgr->loadScene("../media/example.irr");

	/* 
	That was it already. Now add a camera and draw the scene
	*/

	// add a user controlled camera

	smgr->addCameraSceneNodeFPS();


  /* now we are ready to run our script */
  if (!JS_EvaluateScript(context, global,script, strlen(script),
			 "script", 1, &rval))
  {
    std::cout << "Failure in running the script\n";
    //return EXIT_FAILURE;
  }

	// and draw everything.

	int lastFPS = -1;

	while(device->run())
	if (device->isWindowActive())
	{
		driver->beginScene(true, true, video::SColor(0,200,200,200));
		smgr->drawAll();
		driver->endScene();

		int fps = driver->getFPS();

		if (lastFPS != fps)
		{
		  core::stringw str = L"Load Irrlicht File example - Irrlicht Engine [";
		  str += driver->getName();
		  str += "] FPS:";
		  str += fps;

		  device->setWindowCaption(str.c_str());
		  lastFPS = fps;
		}

	}

	device->drop();




  /* clean up */
  JS_DestroyContext(context);
  JS_DestroyRuntime(runtime);
  JS_ShutDown();
  return EXIT_SUCCESS;
}


dlangdev
Posts: 1324
Joined: Tue Aug 07, 2007 7:28 pm
Location: Beaverton OR
Contact:

Post by dlangdev »

Just for fun, I made the logo for BrokenFinger

Image
Post Reply