2007-06-10

AS3 與 AMFPHP 1.2 part 3 - Credentials

AS3 沒有 setCredentials() 了
而是利用 NetConnection.addHeader(), 下兩行是 Help 裡說明
Adds a context header to the AMF packet structure.
This header is sent with every future AMF packet.

Flash AS3:
var nc:NetConnection = new NetConnection();
nc.objectEncoding = ObjectEncoding.AMF0;
nc.connect('http://localhost/amfphp/gateway.php');
nc.addHeader("Credentials", false,
{userid:'kitty', password:'kitty'});

var responder:Responder = new Responder(onResult, onError);
nc.call('myremoting.DataOp_6.isLogin', responder);

function onResult(re:Object):void {
QopDump.echo(re);
}
function onError(er:Object):void {
QopDump.echo(er);
}

AS3 與 AMFPHP 1.2 part 2

後台傳送資料表至前端的「格式」
DataOp_2.php 原始碼
< ?php
class DataOp_2
{
var $dbhost = "localhost";
var $db = "test";
var $table = "tbl_address_book";
var $user = "root";
var $password = "admin";

function DataOp_2(){
mysql_connect($this->dbhost, $this->user, $this->password);
mysql_query("SET NAMES 'utf8'");
mysql_select_db($this->db);

$this->methodTable = array(
"getAllData"=>array(
"access"=>"remote"
)
);
}

function getAllData(){
$sql = sprintf("select * from `%s`", $this->table);
return mysql_query($sql);
}
}
?>

Flash AS3
import QopDump; // just prompt

var nc:NetConnection = new NetConnection();
nc.connect('http://localhost/amfphp/gateway.php');
var responder:Responder = new Responder(onResult, onError);
nc.call('myremoting.DataOp_2.getAllData', responder);

function onResult(re:Object):void {
QopDump.echo(re);
}
function onError(er:Object):void {
QopDump.echo(er);
}

正常執行的結果:
serverInfo:
version:1
id:
serviceName:PageAbleResult
initialData:
[0]:
[0]:3
[1]:哈利
[2]:0987654321
[3]:台北市大安區
[1]:
[0]:4
[1]:凱蒂貓
[2]:0987654322
[3]:宜蘭縣礁溪鄉
[2]:
[0]:6
[1]:小叮噹
[2]:0987654323
[3]:台東縣知本溫泉旁
columnNames:
[0]:id
[1]:name
[2]:phone
[3]:address
cursor:1
totalCount:3

方法名稱錯誤的結果:
line:171
description:The method {getAll} was not declared in the meta data for class {DataOp_2}.
level:User Error
details:C:\wamp163\www\amfphp\amf-core\app\Actions.php
code:AMFPHP_UNDECLARED_METHOD

AS3 與 AMFPHP 1.2 part 1

AS3 object serialization 預設為 AMF3, 後台若使用 AMFPHP 1.2
且要由 AS3 送資料紿後台時, 記得要設定成 AMF0 的格式溝通
var nc:NetConnection = new NetConnection();
// 設定為 AMF0, 預設值為 AMF3
nc.objectEncoding = ObjectEncoding.AMF0;
nc.connect('http://localhost/amfphp/gateway.php');

2007-06-09

QopDump - Dump 的 AS3 版

改寫以前 AS2 的 Dump
使用方式
var a:Object = ["sd","tg","rt",{a:"1", b:"23", c:"11"}];
// 取得字串資料用 QopDump.go(a)
// 直接 trace
QopDump.echo(a);

執行結果:
[0]:sd
[1]:tg
[2]:rt
[3]:
c:11
a:1
b:23

原始檔 QopDump.as
/**
* author: shinder lin
* email: shinder.lin@gmail.com
*/
package {
import flash.utils.describeType;
public class QopDump {
static var n:int = 0;
static var str:String;
// trace
public static function echo(o:Object):void {
trace( go(o) );
}
// return the result string
public static function go(o:Object):String {
str = "";
dump(o);
// remove the lastest \n
str = str.slice(0, str.length-1);
return str;
}
static function dump(o:Object) {
var type:String = describeType(o).@name;
if(type == 'Array') {
dumpArray(o);
} else if (type == 'Object') {
dumpObject(o);
} else {
appendStr(o);
}
}
static function appendStr(s:Object) {
str += s + '\n';
}
static function dumpArray(a:Object):void {
n++;
var type:String;
for (var i:String in a) {
type = describeType(a[i]).@name;
if (type == 'Array' || type == 'Object') {
appendStr(getSpaces() + "[" + i + "]:");
dump(a[i]);
} else {
appendStr(getSpaces() + "[" + i + "]:" + a[i]);
}
}
n--;
}
static function dumpObject(o:Object):void {
n++;
var type:String;
for (var i:String in o) {
type = describeType(o[i]).@name;
if (type == 'Array' || type == 'Object') {
appendStr(getSpaces() + i + ":");
dump(o[i]);
} else {
appendStr(getSpaces() + i + ":" + o[i]);
}
}
n--;
}
static function getSpaces():String {
var s:String ="";
for(var i:int = 1; i < n; i++){
s += " ";
}
return s;
}
}
}

2007-06-08

describeType() 是判斷型別的好工具

flash.utils.describeType() 是判斷型別的好工具
Flash AS3:
var a:Object = 123;
var b:Object = 1e-1;
var c:Object = {a:1,b:2};
var d:Object = [5,4,3];
var e:Object = 'sss';
trace(describeType(a).@name);
trace(describeType(b).@name);
trace(describeType(c).@name);
trace(describeType(d).@name);
trace(describeType(e).@name);

Output:
int
Number
Object
Array
String

AS3 堆疊溢位

AS2 的遞迴限制是 255 次
AS3 顯然好多了, 我測試的結果是 6898 次
不知道是否跟系統資源相關
function sum(n:int):int{
trace(n);
if(n < 2)
return 1;
else
return n+sum(n-1);
}
trace(sum(6900));

Error #1023: 發生堆疊溢位

Adobe CS3 中文版於 7/12 發表

Adobe CS3中文版將於七月發表
CS3 中文版上市日程
於7月12日
假 THCC 台大醫院國際會議中心舉辦

把 JavaScript 當作 temporary data pool (AS3 和 AS2 溝通)

將 SWF9(from Flex2)收到的 Flashvars 變數, 傳給 JS
SWF8 需要時或被載入後再由 JS 取出
SWF9: AS3
private var paramObj:Object;
private function init():void{
paramObj = Application.application.parameters;
ExternalInterface.call('setMyVars', paramObj);
}

JavaScript:
var myVars;
function setMyVars(v){
myVars = v;
/*
var s='';
for(var i in v){
s+= i+' : '+v[i]+'\n';
}
alert(s);
*/
}
function getMyVars(){
return myVars;
}

SWF8: AS2
import flash.external.ExternalInterface;
var myVars = ExternalInterface.call('getMyVars');

JavaScript 的 alert() 有時也是個很好的除錯工具

AS3 和 AS2 溝通

Adobe CS3 才上市不久, 大部份的人對 Flash CS3 不是頂熟稔
若要使用 ActionScript 3 的新功能, 卻又想以熟悉的 Flash 8 開發
遇到的最大問題就是 ActionScrip 3 和 ActionScript 2 的溝通
目前常用的作法有兩種: LocalConnection 和 ExternalInterface

在使用 SWF 9 (from Flex 2) 載入 SWF 8 (from Flash 8) 的情況下, 使用文字資料做測試
LocalConnection 每次只能傳送低於 40K 的資料
透過 ExternalInterface 則可以傳遞超過 1M 的資料給 JavaScript

LocalConnection 明顯只適用於傳遞少量資料
缺點: 接收的 SWF 實體只能有一個 (第二個實體之後是收不到資料的)
優點: 不限實體的執行形式 (EXE, flash player, flash plugin)
ExternalInterface 的缺點是必須要有 plugin container 當中介的角色

之前遇到的一個情況是 SWF9 載入兩支 SWF8 (a 和 b)
● SWF8a 負責和使用者互動, 讓使用者編輯
● SWF8b 負責產生上傳的圖片
● SWF9 負責將 SWF8b 的內容上傳
SWF8a 透過 EI 傳遞 XML 給 SWF8b 產生圖片
SWF8b 完成圖片後, 透過 EI 叫 SWF9 上傳圖片

SWF8a: AS2
import flash.external.ExternalInterface;
ExternalInterface.call("toRender", _xml.toString());

JavaScript:
function toRender(str){
if(navigator.appName.indexOf("Microsoft") != -1){
window.room_planner.renderPic(str);
}else{
window.document.room_planner.renderPic(str);
}
return true;
}
function uploadImage(){
if(navigator.appName.indexOf("Microsoft") != -1){
window.room_planner.uploadImage();
}else{
window.document.room_planner.uploadImage();
}
return true;
}

SWF8b: AS2
import flash.external.ExternalInterface;
var successRegist = ExternalInterface.addCallback("renderPic", null, render);
//
function render(d_str) {
// loading objects ...
onEnterFrame = sdEnterFrame;
}
function sdEnterFrame() {
var all_loaded = true;
for (var i = 0; i < loadee_ar.length; i++) {
if (loadee_ar[i].c_mc.getBytesLoaded() < 10) {
all_loaded = false;
break;
}
}
if (all_loaded) {
resizeToUpload();
ExternalInterface.call('uploadImage');
delete this.onEnterFrame;
}
}

SWF9: AS3
private function init():void{
// ...
ExternalInterface.addCallback('uploadImage', uploadImage);
}
private function uploadImage():void{
pop = PopUpManager.createPopUp(this, MyMsgWin, true);
pop.x = 440;
pop.y = 296;

var timer:Timer = new Timer(500, 1);
timer.addEventListener(TimerEvent.TIMER_COMPLETE, doUploadImage);
timer.start();
}

換用免錢的暴露閣

Shinder's List 已經停擺許久了
最近又想寫點東西, 但懶得處理垃圾廣告, 所以轉到 Blogger
Shinder's List 可能會無預警倒站
部份文章會在這改寫再重貼

FB 留言