Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Includes
- #include <FlashRuntimeExtensions.h>
- #include <Box2D/Box2D.h>
- #include <vector>
- #include <string.h>
- #include <pthread.h>
- #include <unistd.h>
- #ifdef __cplusplus
- extern "C" {
- #endif
- //Global Variables
- //The Box2D World
- b2World *g_World = 0;
- //Vector of Box2D Bodies
- std::vector<b2Body*> bodies;
- //My attempt at locks. Lock is for main thread, innerlock is for simulate thread.
- int lock = 0;
- int innerlock = 0;
- //Hardcoded for now, can hold up to 500 bodies + the one terminating id of -1.0 so AS3 can exit early.
- double values[2001];
- //Declarations
- //ANE stuff
- void ExtensionInitializer(void **externalDataToSet, FREContextInitializer *init, FREContextFinalizer *clean);
- void ContextInitializer(void *externalData, const uint8_t *contextType, FREContext context, uint32_t *numFunctionsToSet, const FRENamedFunction **functionsToSet);
- void ContextFinalizer(FREContext context);
- void ExtensionFinalizer();
- //Functiona AS3 can call
- FREObject CreateBox2DWorld(FREContext ctx, void *functionData, uint32_t argc, FREObject argv[]);
- FREObject Step(FREContext ctx, void *functionData, uint32_t argc, FREObject argv[]);
- FREObject AddBox(FREContext ctx, void *functionData, uint32_t argc, FREObject argv[]);
- //The Simulation Thread Method
- void* threadMethod(void* data) {
- //Forever loop
- while(true) {
- //So long as we're not adding a box or asking for the data to go back to AS3...
- if (lock == 0) {
- //Lock our inner thread
- innerlock = 1;
- //Step the world
- g_World->Step(1.0f/60.0f, 6, 2);
- std::vector<b2Body*>::const_iterator it;
- int vectorIndex = 0;
- b2Vec2 position;
- float32 angle;
- //Iterate through all bodies
- for (it = bodies.begin(); it != bodies.end(); ++it) {
- //Only if it's awake
- if ((*it)->IsAwake()) {
- //Get values off the body
- position = (*it)->GetPosition();
- angle = (*it)->GetAngle();
- //Store in the values array and compensate for Flash's units and coordinate space. Hardcoded.
- values[vectorIndex] = (*it)->physID;
- vectorIndex++;
- values[vectorIndex] = (position.x * 10.0) + 512.0;
- vectorIndex++;
- values[vectorIndex] = (position.y * -10.0) + 300.0;
- vectorIndex++;
- values[vectorIndex] = (angle * 180.0/3.14159265);
- vectorIndex++;
- }
- }
- //Write a terminating id so flash can exit early.
- values[vectorIndex] = -1.0;
- //Unlock our inner thread
- innerlock = 0;
- }
- }
- return 0;
- }
- //Implementations
- FREObject CreateBox2DWorld(FREContext ctx, void *functionData, uint32_t argc, FREObject argv[]) {
- FRESetContextActionScriptData(ctx, argv[2]);
- //Result to Return
- FREObject result = 0;
- double xGravity = 0.0;
- double yGravity = 0.0;
- if (FREGetObjectAsDouble(argv[0], &xGravity) != FRE_OK) {
- FRENewObjectFromBool(0, &result);
- return result;
- }
- if (FREGetObjectAsDouble(argv[1], &yGravity) != FRE_OK) {
- FRENewObjectFromBool(0, &result);
- return result;
- }
- //Pretty simple stuff, this method is only called once and just creates a new world with a ground that we can collide with.
- b2Vec2 gravity(xGravity, yGravity);
- g_World = new b2World(gravity);
- //TEMP CODE FOR TESTING
- b2BodyDef groundBodyDef;
- groundBodyDef.position.Set(0.0f, -30.0f);
- b2Body* groundBody = g_World->CreateBody(&groundBodyDef);
- b2PolygonShape groundBox;
- groundBox.SetAsBox(50.0f, 10.0f);
- groundBody->CreateFixture(&groundBox, 0.0f);
- //Create the thread and simulate forever!
- pthread_create(0, 0, threadMethod, 0);
- FRENewObjectFromBool(1, &result);
- return result;
- }
- FREObject AddBox(FREContext ctx, void *functionData, uint32_t argc, FREObject argv[]) {
- //So long as the inner thread is busy, we need to wait
- while(innerlock == 1) {
- //do nothing
- }
- //Then lock the main thread
- lock = 1;
- FREObject result = 0;
- //Get values from AS3 and use them in C
- double id;
- FREGetObjectAsDouble(argv[0], &id);
- double posX;
- double posY;
- FREGetObjectAsDouble(argv[1], &posX);
- FREGetObjectAsDouble(argv[2], &posY);
- //Create a new body
- b2Body* body;
- b2BodyDef bodyDef;
- bodyDef.type = b2_dynamicBody;
- bodyDef.position.Set(posX, posY);
- body = g_World->CreateBody(&bodyDef);
- b2PolygonShape dynamicBox;
- dynamicBox.SetAsBox(1.0f, 1.0f);
- b2FixtureDef fixtureDef;
- fixtureDef.shape = &dynamicBox;
- fixtureDef.density = 1.0f;
- fixtureDef.friction = 0.3f;
- body->CreateFixture(&fixtureDef);
- //Hacked onto the Body.h file for proof of concept
- body->physID = id;
- //Store bodies so we can easily iterate in the simulation thread
- bodies.push_back(body);
- //Unlock the main thread
- lock = 0;
- FRENewObjectFromBool(1, &result);
- return result;
- }
- FREObject Step(FREContext ctx, void *functionData, uint32_t argc, FREObject argv[]) {
- //Same thing, if the simualation thread is busy, wait.
- while(innerlock == 1) {
- //do nothing
- }
- //Lock the main thread
- lock = 1;
- //Gets access to AS3 ByteArray
- FREObject bytes = 0;
- FREGetContextActionScriptData(ctx, &bytes);
- FREByteArray byteArray;
- FREAcquireByteArray(bytes, &byteArray);
- //Copies the values array that was populated in the simulate thread into the bytearray.
- memcpy(byteArray.bytes, &values, byteArray.length);
- FREReleaseByteArray(bytes);
- //Release the main thread
- lock = 0;
- return 0;
- }
- void ExtensionInitializer(void **externalDataToSet, FREContextInitializer *init, FREContextFinalizer *clean) {
- externalDataToSet = 0;
- *init = &ContextInitializer;
- *clean = &ContextFinalizer;
- }
- void ContextInitializer(void *externalData, const uint8_t *contextType, FREContext context, uint32_t *numFunctionsToSet, const FRENamedFunction **functionsToSet) {
- static FRENamedFunction s_classMethods[] = {
- {(const uint8_t *)"createBox2DWorld", 0, CreateBox2DWorld},
- {(const uint8_t *)"step", 0, Step},
- {(const uint8_t *)"addBox", 0, AddBox}
- };
- const int methodCount = sizeof(s_classMethods) / sizeof(FRENamedFunction);
- *functionsToSet = s_classMethods;
- *numFunctionsToSet = methodCount;
- }
- void ContextFinalizer(FREContext context) {
- //Handle Clean up
- if (g_World) {
- delete g_World;
- g_World = 0;
- }
- pthread_exit(NULL);
- }
- void ExtensionFinalizer() {
- }
- #ifdef __cplusplus
- }
- #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement