Advertisement
Guest User

Jon_one

a guest
Mar 1st, 2012
455
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.28 KB | None | 0 0
  1. //Includes
  2. #include <FlashRuntimeExtensions.h>
  3. #include <Box2D/Box2D.h>
  4. #include <vector>
  5. #include <string.h>
  6. #include <pthread.h>
  7. #include <unistd.h>
  8.  
  9.  
  10. #ifdef __cplusplus
  11. extern "C" {
  12. #endif
  13.  
  14.  
  15. //Global Variables
  16. //The Box2D World
  17. b2World *g_World = 0;
  18.  
  19. //Vector of Box2D Bodies
  20. std::vector<b2Body*> bodies;
  21.  
  22. //My attempt at locks. Lock is for main thread, innerlock is for simulate thread.
  23. int lock = 0;
  24. int innerlock = 0;
  25.  
  26. //Hardcoded for now, can hold up to 500 bodies + the one terminating id of -1.0 so AS3 can exit early.
  27. double values[2001];
  28.  
  29.  
  30.  
  31. //Declarations
  32.  
  33. //ANE stuff
  34. void ExtensionInitializer(void **externalDataToSet, FREContextInitializer *init, FREContextFinalizer *clean);
  35. void ContextInitializer(void *externalData, const uint8_t *contextType, FREContext context, uint32_t *numFunctionsToSet, const FRENamedFunction **functionsToSet);
  36.  
  37. void ContextFinalizer(FREContext context);
  38. void ExtensionFinalizer();
  39.  
  40. //Functiona AS3 can call
  41. FREObject CreateBox2DWorld(FREContext ctx, void *functionData, uint32_t argc, FREObject argv[]);
  42. FREObject Step(FREContext ctx, void *functionData, uint32_t argc, FREObject argv[]);
  43. FREObject AddBox(FREContext ctx, void *functionData, uint32_t argc, FREObject argv[]);
  44.  
  45.  
  46.  
  47. //The Simulation Thread Method
  48. void* threadMethod(void* data) {
  49.  
  50.     //Forever loop
  51.     while(true) {
  52.         //So long as we're not adding a box or asking for the data to go back to AS3...
  53.         if (lock == 0) {
  54.             //Lock our inner thread
  55.             innerlock = 1;
  56.             //Step the world
  57.             g_World->Step(1.0f/60.0f, 6, 2);
  58.  
  59.  
  60.             std::vector<b2Body*>::const_iterator it;
  61.  
  62.             int vectorIndex = 0;
  63.  
  64.             b2Vec2 position;
  65.             float32 angle;
  66.  
  67.             //Iterate through all bodies
  68.             for (it = bodies.begin(); it != bodies.end(); ++it) {
  69.                 //Only if it's awake
  70.                 if ((*it)->IsAwake()) {
  71.  
  72.                     //Get values off the body
  73.                     position = (*it)->GetPosition();
  74.                     angle = (*it)->GetAngle();
  75.  
  76.                     //Store in the values array and compensate for Flash's units and coordinate space. Hardcoded.
  77.                     values[vectorIndex] = (*it)->physID;
  78.                     vectorIndex++;
  79.                     values[vectorIndex] = (position.x * 10.0) + 512.0;
  80.                     vectorIndex++;
  81.                     values[vectorIndex] = (position.y * -10.0) + 300.0;
  82.                     vectorIndex++;
  83.                     values[vectorIndex] = (angle * 180.0/3.14159265);
  84.                     vectorIndex++;
  85.                 }
  86.             }
  87.             //Write a terminating id so flash can exit early.
  88.             values[vectorIndex] = -1.0;
  89.             //Unlock our inner thread
  90.             innerlock = 0;
  91.         }
  92.     }
  93.  
  94.  
  95.  
  96.  
  97.     return 0;
  98. }
  99.  
  100. //Implementations
  101.  
  102. FREObject CreateBox2DWorld(FREContext ctx, void *functionData, uint32_t argc, FREObject argv[]) {
  103.  
  104.  
  105.     FRESetContextActionScriptData(ctx, argv[2]);
  106.  
  107.     //Result to Return
  108.     FREObject result = 0;
  109.  
  110.     double xGravity = 0.0;
  111.     double yGravity = 0.0;
  112.  
  113.     if (FREGetObjectAsDouble(argv[0], &xGravity) != FRE_OK) {
  114.         FRENewObjectFromBool(0, &result);
  115.         return result;
  116.     }
  117.     if (FREGetObjectAsDouble(argv[1], &yGravity) != FRE_OK) {
  118.         FRENewObjectFromBool(0, &result);
  119.         return result;
  120.     }
  121.  
  122.  
  123.  
  124.  
  125.     //Pretty simple stuff, this method is only called once and just creates a new world with a ground that we can collide with.
  126.     b2Vec2 gravity(xGravity, yGravity);
  127.  
  128.  
  129.     g_World = new b2World(gravity);
  130.  
  131.  
  132.     //TEMP CODE FOR TESTING
  133.     b2BodyDef groundBodyDef;
  134.     groundBodyDef.position.Set(0.0f, -30.0f);
  135.  
  136.     b2Body* groundBody = g_World->CreateBody(&groundBodyDef);
  137.  
  138.     b2PolygonShape groundBox;
  139.     groundBox.SetAsBox(50.0f, 10.0f);
  140.  
  141.  
  142.     groundBody->CreateFixture(&groundBox, 0.0f);
  143.  
  144.     //Create the thread and simulate forever!
  145.     pthread_create(0, 0, threadMethod, 0);
  146.  
  147.     FRENewObjectFromBool(1, &result);
  148.     return result;
  149. }
  150.  
  151. FREObject AddBox(FREContext ctx, void *functionData, uint32_t argc, FREObject argv[]) {
  152.  
  153.     //So long as the inner thread is busy, we need to wait
  154.     while(innerlock == 1) {
  155.         //do nothing
  156.     }
  157.     //Then lock the main thread
  158.     lock = 1;
  159.  
  160.     FREObject result = 0;
  161.  
  162.     //Get values from AS3 and use them in C
  163.     double id;
  164.     FREGetObjectAsDouble(argv[0], &id);
  165.  
  166.     double posX;
  167.     double posY;
  168.  
  169.     FREGetObjectAsDouble(argv[1], &posX);
  170.     FREGetObjectAsDouble(argv[2], &posY);
  171.  
  172.  
  173.  
  174.     //Create a new body
  175.     b2Body* body;
  176.     b2BodyDef bodyDef;
  177.     bodyDef.type = b2_dynamicBody;
  178.     bodyDef.position.Set(posX, posY);
  179.  
  180.  
  181.  
  182.     body = g_World->CreateBody(&bodyDef);
  183.  
  184.     b2PolygonShape dynamicBox;
  185.     dynamicBox.SetAsBox(1.0f, 1.0f);
  186.  
  187.     b2FixtureDef fixtureDef;
  188.     fixtureDef.shape = &dynamicBox;
  189.  
  190.     fixtureDef.density = 1.0f;
  191.     fixtureDef.friction = 0.3f;
  192.  
  193.     body->CreateFixture(&fixtureDef);
  194.  
  195.     //Hacked onto the Body.h file for proof of concept
  196.     body->physID = id;
  197.  
  198.     //Store bodies so we can easily iterate in the simulation thread
  199.     bodies.push_back(body);
  200.  
  201.     //Unlock the main thread
  202.     lock = 0;
  203.  
  204.  
  205.     FRENewObjectFromBool(1, &result);
  206.     return result;
  207. }
  208.  
  209. FREObject Step(FREContext ctx, void *functionData, uint32_t argc, FREObject argv[]) {
  210.  
  211.     //Same thing, if the simualation thread is busy, wait.
  212.     while(innerlock == 1) {
  213.         //do nothing
  214.     }
  215.     //Lock the main thread
  216.     lock = 1;
  217.  
  218.     //Gets access to AS3 ByteArray
  219.     FREObject bytes = 0;
  220.     FREGetContextActionScriptData(ctx, &bytes);
  221.  
  222.     FREByteArray byteArray;
  223.     FREAcquireByteArray(bytes, &byteArray);
  224.  
  225.     //Copies the values array that was populated in the simulate thread into the bytearray.
  226.     memcpy(byteArray.bytes, &values, byteArray.length);
  227.  
  228.  
  229.     FREReleaseByteArray(bytes);
  230.  
  231.     //Release the main thread
  232.     lock = 0;
  233.  
  234.     return 0;
  235. }
  236.  
  237.  
  238.  
  239. void ExtensionInitializer(void **externalDataToSet, FREContextInitializer *init, FREContextFinalizer *clean) {
  240.     externalDataToSet = 0;
  241.     *init = &ContextInitializer;
  242.     *clean = &ContextFinalizer;
  243. }
  244.  
  245.  
  246. void ContextInitializer(void *externalData, const uint8_t *contextType, FREContext context, uint32_t *numFunctionsToSet, const FRENamedFunction **functionsToSet) {
  247.  
  248.  
  249.     static FRENamedFunction s_classMethods[] = {
  250.             {(const uint8_t *)"createBox2DWorld", 0, CreateBox2DWorld},
  251.             {(const uint8_t *)"step", 0, Step},
  252.             {(const uint8_t *)"addBox", 0, AddBox}
  253.     };
  254.     const int methodCount = sizeof(s_classMethods) / sizeof(FRENamedFunction);
  255.  
  256.     *functionsToSet = s_classMethods;
  257.     *numFunctionsToSet = methodCount;
  258.  
  259. }
  260.  
  261. void ContextFinalizer(FREContext context) {
  262.     //Handle Clean up
  263.  
  264.  
  265.     if (g_World) {
  266.  
  267.         delete g_World;
  268.         g_World = 0;
  269.     }
  270.  
  271.     pthread_exit(NULL);
  272. }
  273.  
  274. void ExtensionFinalizer() {
  275.  
  276. }
  277.  
  278. #ifdef __cplusplus
  279. }
  280. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement