守望者--AIR技术交流

标题: Crossbridge sample 02 Interop [打印本页]

作者: 破晓    时间: 2015-1-4 17:27
标题: Crossbridge sample 02 Interop
Crossbridge = FlasCC = Alchemy

接續上一篇Crossbridge 編譯後運行 Sample 1 HelloWorld

如果是用 Java 32 的話,先修改D:Crossbridge_1.0.1samples_Interop內的Makefile在4、7、10、13行的後面輸入 -jvmopt=-Xmx1G

[attach]174[/attach]

運行D:Crossbridge_1.0.1內的run.bat,並輸入cd 02_Interop,再輸入make,會編譯4個檔案,我等了5分鐘,有點久看來我應該換個給力一點的電腦,換了一台 i7 3770 編譯了1分半

[attach]175[/attach]

分別是編譯這4個檔案
hellointerop.c 編譯成 hellointerop.exe 和 hellointerop.swf
c++interop.cpp 編譯成 c++interop.swf
bitmapdata.cpp 編譯成 bitmapdata.swf

[attach]176[/attach]

首先讓我們來運行一下 hellointerop.exe,輸入./hellointerop

[attach]177[/attach]

再來看一下 hellointerop.swf

[attach]178[/attach]

之後 c++interop.swf

[attach]179[/attach]

最後 bitmapdata.swf

[attach]180[/attach]

總覺得 c++interop.swf 和 bitmapdata.swf 檔案竟然如此大,2973k和2934k,這種簡單的畫圈圈效果,用AS3的graphics就可畫出來,而且應該用不到2MB吧!



附件02_Interop.rar



[attach]181[/attach]

作者: 破晓    时间: 2015-1-4 17:35
Crossbridge sample 02 Interop 分析 hellointerop.c

開啟 hellointerop.c
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include "AS3/AS3.h"

  4. int main(int argc, char **argv)
  5. {
  6.     // flascc uses GCC's inline asm syntax to allow you to write arbitrary
  7.     // ActionScript inside your C/C++ code. This allows for very easy interop
  8.     // between AS3 and C/C++.
  9.     // flascc 使用 GCC 的行內組合語言語法,允許你寫任意的 ActionScript 到
  10.     // 你的 C/C++ 代碼內。這樣可以非常容易的交互操作於 AS3 和 C/C++之間。
  11.     //
  12.     // For a complete guide to the asm statement and how it is used read the
  13.     // GCC documentation: [url=http://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html]http://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html[/url]
  14.     // or: [url]http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html[/url]
  15.     // 完整的組合語言敘述句引導,並且如何使用之,請參閱 GCC 文檔:
  16.     // [url]http://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html[/url][/url] 或:
  17.     // [url]http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html[/url][/url]
  18.     //
  19.     // Behind the scenes flascc turns each function/method in your C/C++ code
  20.     // into an AS3 function. The only reason for mentioning this is that this
  21.     // of course limits what AS3 you can put in an inline asm statement inside
  22.     // a function. You can't write an AS3 class declaration inside an inline
  23.     // asm statement inside a C/C++ function. You can however write a class
  24.     // declaration outside any C/C++ function.
  25.     // flascc 在幕後把每個 C/C++代碼的函數/方法轉成 AS3 的函數。提到這點
  26.     // 的目的是因為,這理所當然限制了你可以放在行內組合語言敘述句的 AS3
  27.     // 你不能在 C/C++ 函數內的行內組合語言敘述句寫 AS3 類宣告。然而你
  28.     // 可以在任何 C/C++ 函數外面寫類宣告。

  29.     // The following asm statment declares an AS3 variable and traces it out.
  30.     // Because this asm statement doesn't mention any output parameters it must
  31.     // be marked as volatile or GCC will optimise it away.
  32.     // 以下的組合語言敘述句宣告一個 AS3 變數,並且 trace 之。
  33.     // 因為此組合語言敘述句沒有提到任何標記為 volatile 變數的輸出參數,所以
  34.     // GCC 將會優化之。
  35.     //
  36.     // Note: This will not be visible in the SWF console; trace() output goes to
  37.     // the flashlog file. For more information on how to enable trace output
  38.     // visit: [url]http://kb2.adobe.com/cps/403/kb403009.html[/url][/url]
  39.     // 注意: 無法在 SWF 控制台看到此輸出; trace() 輸出進到 flashlog 檔案。
  40.     // 關於如何能 trace 輸出的更多資訊,請參閱
  41.     // [url]http://kb2.adobe.com/cps/403/kb403009.html[/url][/url]

  42.     inline_as3(
  43.         "var foo:int = 42;\n"
  44.         "trace(\"This is inline AS3: \" + foo);\n"
  45.         : :
  46.     );

  47.     // asm statements can take input and output parameters like this. This
  48.     // allows for very easy interop between the two languages.
  49.     // 組合語言敘述句能夠像此一樣獲得輸入和輸出。此允許兩個語言間很容易
  50.     // 的交互操作。
  51.     //
  52.     // Not all C/C++ types have an equivalent in actionscript. They are mapped
  53.     // as follows:
  54.     // 並非所有的 C/C++ 類型在 actionscript 都有等價之類型。其映射如下:
  55.     //
  56.     // C Type        | AS3 Type
  57.     // 32bit int     | int
  58.     // 64bit int     | special handling required! 需要特別處理!
  59.     // 32bit float   | Number
  60.     // 64bit double  | Number
  61.     // pointer       | int

  62.     // Use AS3 to negate a 32bit int!
  63.     // 使用 AS3 把 32 位元 int 變成負數
  64.     int someint = 123;
  65.     int intresult = 0;
  66.     inline_as3(
  67.         //指定%0為負的%1
  68.         "%0 = -%1;\n"
  69.         //%0是intersult
  70.         : "=r"(intresult)
  71.         //%1是someint
  72.         : "r"(someint)  
  73.     );

  74.     // Back in C we can take the result and print it out:
  75.     //回到 C 獲得結果並輸出之
  76.     printf("-%d is %d\n", someint, intresult);

  77.     // Use AS3 to sqrt a double!
  78.     // 使用 AS3 把雙精度浮點數開根號
  79.     double somenumber = 45.0;
  80.     double result = 0.0;
  81.     inline_as3(
  82.         //把%1開根號指定給%0
  83.         "%0 = Math.sqrt(%1);\n"
  84.         //%0 是 result,%1 是 somenumber
  85.         : "=r"(result) : "r"(somenumber)
  86.     );

  87.     // Back in C we can take the result and print it out:
  88.     // 回到 C 獲得結果並輸出之
  89.     printf("sqrt of %f is %f\n", somenumber, result);

  90.     // Use AS3 to manipulate a 64bit int!
  91.     // 使用 AS3 操作 64位元 整數
  92.     unsigned long long somelonglong = 0x243F6A8885A308D3ULL; // 64 fractional pi bits 64位元的PI小數部份
  93.     double piapprox = 0.0;

  94.     inline_as3(
  95.         // cast to uint because %1 and %2 will be AS3 int despite "unsigned" C expression type
  96.         // 雖然 C 表態式類型是"unsigned",還是要強制轉型成 uint,因為%1和%2是 AS3 的 int。
  97.         "%0 = 3 + uint(%1) / 0x100000000 + uint(%2) / 0x10000000000000000\n"
  98.         : "=r"(piapprox) : "r"((unsigned)(somelonglong >> 32)), "r"((unsigned)somelonglong));
  99.     printf("pi approx is %.15f\n", piapprox);

  100.     // Now, 64-bit out
  101.     // 現在試試 64位元
  102.     unsigned hi32, lo32;
  103.     inline_as3(
  104.         "%0 = uint(Math.sqrt(2) * 0x100000000); %1 = uint(Math.sqrt(2) * 0x10000000000000000)\n"
  105.         : "=r"(hi32), "=r"(lo32));
  106.     somelonglong = ((unsigned long long)hi32 << 32) | lo32;
  107.     // 輸出根號2的52位尾數是
  108.     printf("52 fractional bits of sqrt(2): %llx\n", somelonglong); // only 52 bit mantissa in double! 在 double 只有 52位尾數

  109.     // Handling C strings involves a bit more work. Although they aren't
  110.     // automatically converted to AS3 String objects when passed in/out of an
  111.     // asm statement there are helper methods available.
  112.     // 處理 C 字串要做更多事。雖然其不是自動轉成 AS3 字串物件,不過當傳遞
  113.     // 進出於組合語言表態式時,有輔助方法。

  114.     const char* words[] = {"flascc", "is", "awesome!"};
  115.     int i;
  116.     for(i=0; i<3; i++) {
  117.         inline_as3(
  118.             "trace(\"trace: \" + %0 +  \": \" + CModule.readString(%1, %2));\n"
  119.             : : "r"(i), "r"(words[i]), "r"(strlen(words[i]))
  120.         );
  121.     }

  122.     // What about passing strings from AS3 into C/C++? Because flascc uses a
  123.     // ByteArray for storage we need to malloc() some space in that ByteArray
  124.     // and copy the string data in.
  125.     // 那要如何從 AS3 傳遞字串到 C/C++呢?因為 flascc 使用一個 ByteArray
  126.     // 來儲存,我們需要在該ByteArray malloc() 一些空間,並從中拷貝字串。
  127.     //
  128.     // The mallocString helper function takes an AS3 string and allocates a
  129.     // copy in the flascc heap. This can then be freed from C using the
  130.     // normal free() function.
  131.     // 此 mallocString 輔助函數,要一個 AS3 字串,並且在 flascc 堆分配
  132.     // 一個拷貝。這樣就可以在 C 使用 free() 函數釋放之。
  133.     //
  134.     // This example also shows that variables declared in one asm block are
  135.     // visible to other asm blocks.
  136.     // 此範例展示在一個組合語言區塊的變數宣告,改變數在其它組合語言區塊可見。

  137.     inline_as3("var as3words = ['Interop', 'is', 'easy!'];\n");
  138.     char* wordptrs[] = {NULL, NULL, NULL};
  139.     for(i=0; i<3; i++) {
  140.         inline_as3(
  141.             "var stringptr:int = CModule.mallocString(as3words[%0]);\n"
  142.             "CModule.write32(%1, stringptr);\n"
  143.             : : "r"(i), "r"(&wordptrs[i])
  144.         );
  145.     }

  146.     for(i=0; i<3; i++) {
  147.         printf(">>> %s\n", wordptrs[i]);
  148.         free(wordptrs[i]);
  149.     }
  150. }
复制代码
名詞解釋
interop 交互操作,應該是 inter 和 operation 的結合。
volatile 變數,用於 C 的變數關鍵字,使 C 編譯器不優化該變數。


作者: 破晓    时间: 2015-1-4 17:36
Crossbridge sample 02 Interop 分析 c++interop.cpp
再來讓我們來看一下 c++interop.cpp
  1. #include <vector>
  2. #include <AS3/AS3.h>
  3. #include <Flash++.h>

  4. // Flash 11.4 introduced a worker-based concurrency model in which each worker
  5. // has access to almost all of the Flash APIs with the one restriction that
  6. // objects on one worker cannot be passed to other workers, all communication
  7. // must happen via special communication APIs (MessageChannel) or via the
  8. // shared ByteArray support (Flash 11.5)
  9. // Flash 11.4 引進了以線程為基礎的並行處理模型,在每一個線程幾乎可以使用
  10. // 所有的 Flash API ,不過有一個限制,一個線程內的物件無法傳遞給其他線程,
  11. // 所有的溝通必須經由特殊的溝通 API(MessageChannel) 或
  12. // 經由 Flash 11.5 支持的共享 ByteArray。
  13. //
  14. // Flash++ contains two sets of bindings for the flash APIs, one that refers to
  15. // objects on the UI worker (the main flash instance that has access to the
  16. // primary display) and another that refers to objects local to a given worker.
  17. // Flash++ 包涵兩個 flash API 的結合設定,其一代表在 UI 線程物件(主
  18. // Flash 實例,其用來做主要顯示),其二代表給定的本地線程物件。
  19. //
  20. // When interacting with "ui" references property access and method calls will
  21. // block until they can be serviced by the main worker when it calls
  22. // CModule.serviceUIRequests() (Which it should be doing on EnterFrame, or on a
  23. // timer).
  24. // 當存取 "ui" 參考屬性,和呼叫方法時,可能會造成阻塞,只有在呼叫
  25. // CModule.serviceUIRequests() (應該用在 EnterFrame 或 timer),它們才可以服務
  26. // 主線程。
  27. //
  28. // Because we will just be using UI references in this example we can avoid the
  29. // need to type the additional "AS3::ui" prefix with a normal C++ using
  30. // declaration.
  31. // 因為我們在此範例將剛好使用 UI 參考,只需於正常的 C++ 輸入 "AS3::ui" 前綴宣告,
  32. // 我們就可以避免此狀況。

  33. using namespace AS3::ui;
  34. // using namespace AS3::local;
  35. // if we wanted everything to be worker-local
  36. // 如果我們想要在本地線程的東西,則using namespace AS3::local;

  37. int main()
  38. {
  39.         // Get a reference to the current stage
  40.         // 獲得目前舞台參考
  41.         flash::display::Stage stage = internal::get_Stage();

  42.         // Just to prove we can lets make a C++ vector containing sprite references
  43.         // 證明我們可以讓 C++ vector 持有 sprite 參考
  44.         std::vector<flash::display::Sprite> sprites;
  45.         int numCircles = 10;

  46.         for(int i=0; i<numCircles; i++) {
  47.                 // Construct a new Sprite object
  48.                 // 建構一個新的 Sprite 物件
  49.                 flash::display::Sprite mySprite = flash::display::Sprite::_new();

  50.                 // Access its "graphics" property to get the canvas we can draw to
  51.                 // 存取其 "graphics" 屬性,來獲得可以畫畫的畫板。
  52.                 flash::display::Graphics graphics = mySprite->graphics;

  53.                 // Draw simple filled circle
  54.                 // 畫簡單的填色圓形
  55.                 graphics->beginFill(0xff00ff, 0.5);
  56.                 graphics->drawCircle(0.0, 0.0, 30.0);
  57.                 graphics->endFill();

  58.                 // Add the sprite into our C++ vector
  59.                 // 把 sprite 加入到 C++ vector
  60.                 sprites.push_back(mySprite);
  61.         }

  62.         // Add the circles to the stage
  63.         // 把圓形加到舞台
  64.         for(int i=0; i<numCircles; i++) {
  65.                 // Take one of the sprites and position it along the diagonal of
  66.                 // the screen
  67.                 // 獲得其中一個 sprite ,並沿著螢幕的對角線擺放
  68.                 flash::display::Sprite s = sprites[i];
  69.                 s->x = i * 25;
  70.                 s->y = i * 25;

  71.                 // Add it to the stage so we can see it
  72.                 // 將其加入到舞台,使我們可以看見之
  73.                 stage->addChild(s);
  74.         }
  75. }
复制代码
也就是說
AS3
import flash.display.Sprite;
var mySprite = new Sprite();
在 Flash++ 要寫成
flash::display::Sprite mySprite = flash::display::Sprite::_new();

AS3
mySprite.graphics.beginFill(0xff00ff, 0.5)
在 Flash++ 要寫成
flash::display::Graphics graphics = mySprite->graphics;
graphics->beginFill(0xff00ff, 0.5);


作者: 破晓    时间: 2015-1-4 17:44
Crossbridge sample 02 Interop 分析 bitmapdata.cpp

最後來看一下 bitmapdata.cpp
  1. #include <AS3/AS3.h>
  2. #include <Flash++.h>

  3. // Flash 11.4 introduced a worker-based concurrency model in which each worker
  4. // has access to almost all of the Flash APIs with the one restriction that
  5. // objects on one worker cannot be passed to other workers, all communication
  6. // must happen via special communication APIs (MessageChannel) or via the
  7. // shared ByteArray support (Flash 11.5)
  8. // Flash 11.4 引進了以線程為基礎的並行處理模型,在每一個線程幾乎可以使用
  9. // 所有的 Flash API ,不過有一個限制,一個線程內的物件無法傳遞給其他線程,
  10. // 所有的溝通必須經由特殊的溝通 API(MessageChannel) 或
  11. // 經由 Flash 11.5 支持的共享 ByteArray。
  12. //
  13. // Flash++ contains two sets of bindings for the flash APIs, one that refers to
  14. // objects on the UI worker (the main flash instance that has access to the
  15. // primary display) and another that refers to objects local to a given worker.
  16. // Flash++ 包涵兩個 flash API 的結合設定,其一代表在 UI 線程物件(主
  17. // Flash 實例,其用來做主要顯示),其二代表給定的本地線程物件。
  18. //
  19. // When interacting with "ui" references property access and method calls will
  20. // block until they can be serviced by the main worker when it calls
  21. // CModule.serviceUIRequests() (Which it should be doing on EnterFrame, or on a
  22. // timer).
  23. // 當存取 "ui" 參考屬性,和呼叫方法時,可能會造成阻塞,只有在呼叫
  24. // CModule.serviceUIRequests() (應該用在 EnterFrame 或 timer),它們才可以服務
  25. // 主線程。
  26. //
  27. // Because we will just be using UI references in this example we can avoid the
  28. // need to type the additional "AS3::ui" prefix with a normal C++ using
  29. // declaration.
  30. // 因為我們在此範例將剛好使用 UI 參考,只需於正常的 C++ 輸入 "AS3::ui" 前綴宣告,
  31. // 我們就可以避免此狀況。

  32. using namespace AS3::ui;
  33. // using namespace AS3::local; // if we wanted everything to be worker-local
  34. // 如果我們想要在本地線程的東西,則using namespace AS3::local;

  35. static const int COORDBITS = 7; // 7 bits => dim of 128 7位是128的dim(模糊不清)
  36. static const int DIM = 1 << COORDBITS; //CORRDBITS精度位

  37. // return a "swizzled" (Morton order -- x/y bits interleaved) offset
  38. // for a given input offset and coordinate bit count
  39. // 對於給定的輸入位移,整合位元計算後,返回 "swizzled(攪和的)"
  40. // (摩頓順序 -- x/y 位交错) 位移值
  41. static int swizzleOffset(int offs)
  42. {
  43.   int result = 0;
  44.   int coordBits = COORDBITS;
  45.   int offsHi = offs >> COORDBITS; // take the higher order bits 獲得更高的位元
  46.   int coordBits2 = COORDBITS * 2;
  47.   while(coordBits--)
  48.   {
  49.     // put the lowest bit in the "lo" offset bits
  50.     // into the highest bit of the result...
  51.     // it'll get shifted into a lower position
  52.     // as the loop executes
  53.     // 把在 "lo" offset 位元的最低位放到結果的最高位
  54.     // 當迴圈執行時,其將移到更低的位子
  55.     result |= ((offs & 1) << coordBits2);
  56.     offs >>= 1;
  57.     result >>= 1;
  58.     // same for the "hi" offset bits
  59.     // 至於 "hi" 位移位元也一樣
  60.     result |= ((offsHi & 1) << coordBits2);
  61.     offsHi >>= 1;
  62.     result >>= 1;
  63.   }
  64.   return result;
  65. }

  66. // swizzle a whole image worth of pixels
  67. // 攪和整個圖片的等值像素
  68. static void swizzlePixels(unsigned *dst, unsigned *src)
  69. {
  70.         int offs = DIM * DIM;

  71.         while(offs--)
  72.         {
  73.                 int swiz = swizzleOffset(offs);
  74.                 dst[swiz] = src[offs];
  75.         }
  76. }

  77. // handle a mouse click and swizzle our BitmapData's pixels
  78. // 處理滑鼠點擊,並攪和位圖資料的像素
  79. static var mouseDownHandler(void *arg, var args)
  80. {
  81.         flash::events::MouseEvent event = flash::events::MouseEvent(args[0]);
  82.         flash::display::Sprite sprite = flash::display::Sprite(event->target); // the container Sprite Sprite容器
  83.         flash::display::Bitmap bitmap = flash::display::Bitmap(sprite->getChildAt(0)); // Bitmap is the only child 位圖是唯一的子物件
  84.         flash::display::BitmapData bitmapData = bitmap->bitmapData;
  85.         // ByteArray corresponding to our ram!
  86.         // C ptrs are equivalent to offsets into this ByteArray
  87.         // ByteArray 對應到記憶體!
  88.         // C 指標等同於進到此 ByteArray 的 offsets
  89.         flash::utils::ByteArray ram = internal::get_ram();

  90.         // allocate space for the pixels
  91.         // 為像素分配空間
  92.         unsigned *src = new unsigned[DIM * DIM];
  93.         unsigned *dst = new unsigned[DIM * DIM];
  94.         // copy current pixels directly to ram
  95.         // 直接拷貝目前的像素到記憶體
  96.         bitmapData->copyPixelsToByteArray(bitmapData->rect, ram, src);
  97.         // swizzle them!
  98.         // 攪和它們!
  99.         swizzlePixels(dst, src);
  100.         // write new pixels directly from ram
  101.         // 直接從記憶體寫新的像素
  102.         bitmapData->setPixels(bitmapData->rect, ram, dst);
  103.         // clean up
  104.         // 清除
  105.         delete dst;
  106.         delete src;
  107.         return internal::_undefined;
  108. }

  109. int main()
  110. {
  111.         // Get a reference to the current stage
  112.         // 獲得目前舞台參考
  113.         flash::display::Stage stage = internal::get_Stage();

  114.         // Create a Shape
  115.         // 創建一個 Shape
  116.         flash::display::Shape myShape = flash::display::Shape::_new();
  117.         // Access its "graphics" property to get the canvas we can draw to
  118.         // 訪問其 "graphics" 屬性,獲得可畫畫的畫板
  119.         flash::display::Graphics graphics = myShape->graphics;

  120.         // Draw simple shape
  121.         // 畫簡單圖形
  122.         graphics->beginFill(0xff00ff, 0.5);
  123.         graphics->drawCircle(64.0, 64.0, 64.0);
  124.         graphics->endFill();
  125.         graphics->beginFill(0xffff00, 0.5);
  126.         graphics->drawCircle(64.0, 64.0, 40.0);
  127.         graphics->endFill();
  128.         graphics->beginFill(0x00ffff, 0.5);
  129.         graphics->drawCircle(64.0, 64.0, 16.0);
  130.         graphics->endFill();

  131.         // Create a BitmapData
  132.         // 創建一個 BitmapData
  133.         flash::display::BitmapData myBitmapData = flash::display::BitmapData::_new(DIM, DIM);
  134.         // Draw the Shape into it
  135.         // 把 Shape 畫到裡面
  136.         myBitmapData->draw(myShape);

  137.         // Create a Bitmap
  138.         // 創建一個 Bitmap
  139.         flash::display::Bitmap myBitmap = flash::display::Bitmap::_new(myBitmapData);

  140.         // wrap it in a Sprite
  141.         // 創建一個 Sprite,並把 Bitmap 放進去
  142.         flash::display::Sprite mySprite = flash::display::Sprite::_new();

  143.         mySprite->addChild(myBitmap);
  144.         // Add a click handler
  145.         // 添加點擊處理
  146.         mySprite->addEventListener("mouseDown", Function::_new(&mouseDownHandler, NULL));

  147.         // Add it to the stage so we can see it
  148.         // 把它加到舞台,使我等可以看見之
  149.         stage->addChild(mySprite);

  150.         // Go async so we can handle the mouseDowns!
  151.         // 到異步,以便吾人可以處理滑鼠按下!
  152.         AS3_GoAsync();

  153.         // Not reached!
  154.         // 不會到達!
  155.         return 0;
  156. }
复制代码
因為有用到多線程,所以記得用 Flash Player 11.4 以上的版本開啟,不然不管如何滑鼠點擊圓圈都不會改變內容,反而會沒有回應。用 Flash Player 11.4 開啟,用滑鼠點擊圓形,就可以攪和圓形,點13次後回到原來的圖形。


[attach]182[/attach][attach]183[/attach] [attach]184[/attach]
[attach]185[/attach] [attach]186[/attach] [attach]187[/attach]
[attach]188[/attach] [attach]189[/attach] [attach]190[/attach]
[attach]191[/attach] [attach]192[/attach] [attach]193[/attach]





作者: 破晓    时间: 2015-1-4 17:53
本系列目录:

初探 Alchemy 之下載篇


Crossbridge 編譯後運行 Sample 1 HelloWorld


Crossbridge sample 02 Interop



Crossbridge sample 03 Drawing






欢迎光临 守望者--AIR技术交流 (http://www.airmyth.com/)