PDA

Просмотр полной версии : dynamic class create


AlDev
11.06.2005, 20:29
Вообщем наступил на грабли...
требуется создать класс через его имя, откопал интересную доку:
http://www.gskinner.com/blog/archives/2003/12/class_locations.html

однако, пробую:

function getInstanceOf(p_fullName:String):Object
{
var classPath:Array = p_fullName.split(".");
var package:Object = _global;
var l = classPath.length-1;
for (var i:Number=0;i<l;i++)
{
package = package[classPath[i]];
}
var c:Function = package[classPath[classPath.length-1]];
var instance:Object = new c();
return instance;
}
var a = getInstanceOf("classes.map.layers.landscape");
trace (a);
stop();

на выходе идёт undefined, хотя класс существует...
не могу понять, в чём проблема...
помогите, pls

Nirth
11.06.2005, 20:40
В моем случае(перед вызовом функции, создал экземпляр, для того чтобы класс импортировался) возвращает object Object, правда я вопроса не понял.
Попробуй удостовериться, что класс существует...потому что если класс не используеться, то он и не импортируеться во флэшку.

function getInstanceOf(p_fullName:String):Object
{
var classPath:Array = p_fullName.split(".");
var package:Object = _global;
var l = classPath.length-1;
for (var i:Number=0;i<l;i++)
{
package = package[classPath[i]];
trace(package)
}
var c:Function = package[classPath[classPath.length-1]];
var instance:Object = new c();
return instance;
}
var b:orange.utils.FPS = new orange.utils.FPS(20);
trace(getInstanceOf("orange.utils.FPS"));

import package.Class в данном случае не помогает.
если мы напишем
import mx.controls
и в test movie нажмем crtl+shift+v то получим

Level #0:
Variable _level0.$version = "WIN 7,0,19,0"

а если

import mx.controls.*
var a = new CheckBox();

то получаем

Global Variables:
Variable _global.mx = [object #1, class 'Object'] {
core:[object #2, class 'Object'] {
UIObject:[function 'symbolOwner'],
UIComponent:[function 'symbolOwner']
},
skins:[object #5, class 'Object'] {
SkinElement:[function 'SkinElement']
},
styles:[object #7, class 'Object'] {
CSSTextStyles:[function 'CSSTextStylesDependency'],
CSSStyleDeclaration:[function 'CSSStyleDeclaration'],
StyleManager:[function 'StyleManager']
},
controls:[object #11, class 'Object'] {
SimpleButton:[function 'symbolOwner'],
Button:[function 'symbolOwner'],
CheckBox:[function 'symbolOwner']
}
}
Level #0:
Variable _level0.$version = "WIN 7,0,19,0"
Variable _level0.a = [object #15] {}

AlDev
11.06.2005, 20:43
хмм... а если нет возможности создать по экземпляру класса?
каким образом тогда можно это обойти?

Nirth
11.06.2005, 20:47
как я уже сказал я не понял сути вопроса, тебе нужно создать в условиях AS1 класс написанный на AS2 ? если так то возможнсть уже присутствует(ибо тебе придеться выбрать в настройках AS2 для Flash 6 или 7) ...или я не догоняю?

s_u_m_p
11.06.2005, 20:52
причем тут в условиях ас1 классы ас2??? человек хочет иметь возможность по названию класса создать объект! это как раз чистый ас2

ну проблемы ты правильно указал, если нету явного упоминания класса, его и не будет в результируещем свф, так что либо в библиотеки создать пустые мувы, которые будут связаны с теми классами которые нужны или запихнуть в свф все нужные классы через мтаск - мне так кажется :)

AlDev
11.06.2005, 20:52
в условиях AS2 создать AS2 class. Это просто пример функции, на самом деле всё это по классам пораспихано и из классов вызывается

если так то возможнсть уже присутствует(ибо тебе придеться выбрать в настройках AS2 для Flash 6 или 7)
малость не понял, что ты хотел сказать этой фразой?

s_u_m_p
11.06.2005, 20:54
потом импорт, это больше деректива к компилятору на сокращение пути к классу, тем более все это действует только в том кадре где импорт указан, естественно в данном случае не поможет....

AlDev
11.06.2005, 20:57
так и думал, что придётся извращаться :(
спасибо за идею с mtasc

да и ещё один тупой вопрос из той-же серии....
как получить аргументы, передаваемые функции, достаточно просто и понятна (через arguments). А вот как эти аргументы потом передать конструктору класса в текущей функции?
то есть юзание
var a = getInstanceOf("classes.map.layers.landscape",val1,val2);
было-бы эквивалентно
var a = new classes.map.layers.landscape(val1,val2);

Nirth
11.06.2005, 21:01
var a = getInstanceOf("classes.map.layers.landscape",val1,val2);
было-бы эквивалентно
var a = new classes.map.layers.landscape(val1,val2);

посмотри в хелпе Function.apply придеться чуть доработать, функцию getInstanceOf()
и всеже я до сих пор не врубаюсь, зачем все это, если можно написать new package.Class();

s_u_m_p
11.06.2005, 21:04
:) Nirth представь момент что ты заранее не знаешь что это будеть new x.a.s.Class1 или new x.a.s.Class2

:) через функшн.апли тоже не пройдет, не тот случай, я думаю тебе просто надо будет написать эквивалент оператора new

AlDev
11.06.2005, 21:07
вообщем есть 10 - 20 принципиально разных классов, экземпляры которых описываются в xml и по описанию создаются. Причём хочется иметь возможность добавлять классы не изменяя того класса, в котором создаются экземпляры этих самых классов. Очень-уж неохота лезть в написаный код.
Таким образом будет достаточно написать класс, прицепить его с помощью mtasc к swf-ке и описать его экземпляры в xml, не затрагивая другие классы

Nirth
11.06.2005, 21:09
Как вариант

/**
*
* @author Nirth
* @version 0.0.2
*/
class orange.utils.Importer
{
/**
* imports classes to the SWF
* @usage orange.utils.Importer.doImport(package1.Class1,package2.Class2 etc);
* @return nothing
*/
public static function doImport ():Void
{
orange.utils.Importer.__getFields (arguments);
}
private static function __getFields (args : Array) : Array
{
var result : Array = new Array ();
for (var item : String in args)
{
//trace(args[item]);
for (var field : String in args [item])
{
result.push (args [item][field]);

//break;

}
}
return result;
}
}



В классе есть лишний метод, это я себе оставил маневр для апгрейда, вообще все можно сократить до одного

Nirth
11.06.2005, 21:11
Nirth представь момент что ты заранее не знаешь что это будеть new x.a.s.Class1 или new x.a.s.Class2

Сделаю класс прокси, который будет решать что создавать.

AlDev
11.06.2005, 21:13
с аргуентами решил не заморачиваться, а передавать всё в одном object конструктору, а он уже сам разберёться :)

s_u_m_p
11.06.2005, 21:18
Сделаю класс прокси, который будет решать что создавать.
ну тогда не надо синтаксиса this ['a' + 'b'] создадим функцию прокси, которая будет решать что создавать

Nirth
11.06.2005, 21:20
вот именно, а откуда this['a'+'b'] ?

s_u_m_p
11.06.2005, 21:22
Как вариант

/**
*
* @author Nirth
* @version 0.0.2
*/
class orange.utils.Importer
{
/**
* imports classes to the SWF
* @usage orange.utils.doImport(package1.Class1,package2.Class2 etc);
* @return nothing
*/
public static function doImport ():Void
{
orange.utils.Importer.__getFields (arguments);
}
private static function __getFields (args : Array) : Array
{
var result : Array = new Array ();
for (var item : String in args)
{
//trace(args[item]);
for (var field : String in args [item])
{
result.push (args [item][field]);

//break;

}
}
return result;
}
}


В классе есть лишний метод, это я себе оставил маневр для апгрейда, вообще все можно сократить до одного

импортировать типа такого?
orange.utils.doImport (package1.Class1,package2.Class2);

или так?
orange.utils.doImport ('package1.Class1','package2.Class2');

Nirth
11.06.2005, 21:23
orange.utils.Importer.doImport(package1.Class1) и тд.
извиняюсь сделал ошибку в коментариях сейчас подправлю.

s_u_m_p
11.06.2005, 21:27
Объясни мне тупому тогда как именно твой класс импортирует?

З.Ы. попробуй создать пустой файл фла, в нем единственную строчку
mx.events.EventDispatcher и посмотри через дебагер импортировался ли класс mx.events.EventDispatcher?

Nirth
11.06.2005, 21:31
В первом кадре пишем

orange.utils.Importer.doImport(mx.controls.CheckBox,mx.controls.DataGrid);

тестируем мувик, и смотрим переменные

Global Variables:
Variable _global.mx = [object #1, class 'Object'] {
core:[object #2, class 'Object'] {
UIObject:[function 'symbolOwner'],
UIComponent:[function 'symbolOwner'],
View:[function 'ViewDependency'] {
prototype:[object #6] {
loadExternal:[function 'loadExternal'],
prepareToLoadMovie:[function 'prepareToLoadMovie'],
waitForUnload:[function 'waitForUnload'],
checkLoadProgress:[function 'checkLoadProgress'],
contentLoaded:[function 'contentLoaded']
}
},
ExternalContent:[function 'ExternalContent'],
ScrollView:[function 'symbolOwner']
},
skins:[object #14, class 'Object'] {
SkinElement:[function 'SkinElement'],
Border:[function 'symbolOwner'],
RectBorder:[function 'symbolOwner'],
CustomBorder:[function 'symbolOwner']
},
styles:[object #19, class 'Object'] {
CSSTextStyles:[function 'CSSTextStylesDependency'],
CSSStyleDeclaration:[function 'CSSStyleDeclaration'],
StyleManager:[function 'StyleManager']
},
controls:[object #23, class 'Object'] {
SimpleButton:[function 'symbolOwner'],
Button:[function 'symbolOwner'],
CheckBox:[function 'symbolOwner'],
scrollClasses:[object #27, class 'Object'] {
ScrollBar:[function 'ScrollBar'],
ScrollThumb:[function 'ScrollThumb']
},
listclasses:[object #30, class 'Object'] {
DataSelector:[function 'DataSelector'],
DataProvider:[function 'DataProvider'],
ScrollSelectList:[function 'ScrollSelectList'],
SelectableRow:[function 'SelectableRow']
},
List:[function 'symbolOwner'],
DataGrid:[function 'symbolOwner'],
gridclasses:[object #37, class 'Object'] {
DataGridColumn:[function 'DataGridColumn'],
DataGridRow:[function 'DataGridRow']
},
TextInput:[function 'symbolOwner']
},
managers:[object #41, class 'Object'] {
DepthManager:[function 'DepthManager']
},
events:[object #43, class 'Object'] {
EventDispatcher:[function 'evtDipatcher'],
UIEventDispatcher:[function 'UIEventDispatcher']
},
effects:[object #46, class 'Object'] {
Tween:[function 'Tween']
}
}
Variable _global.orange = [object #48, class 'Object'] {
utils:[object #49, class 'Object'] {
Importer:[function 'Importer']
}
}
Level #0:
Variable _level0.$version = "WIN 7,0,19,0"
Movie Clip: Target="_level0.reserved"

с EventDispatcherom такая же история.

s_u_m_p
11.06.2005, 21:33
еще раз: случай без твоего класса:

попробуй создать пустой файл фла, в нем единственную строчку
mx.events.EventDispatcher и посмотри через дебагер импортировался ли класс mx.events.EventDispatcher?

Nirth
11.06.2005, 21:37
это баг, который возможно устранят. если ты посмотришь в код EventDispatcher'a то заметишь там такую строчку new EventDispatcher - без скобок, тоесть на данный момент, это работает, но по идее класс импортироваться не должен(а в друг у меня просто в глобале такие объекты есть?) так что если макромедия пофиксит данную фичу думаю такой вариант работать не будет
ИМХО.

s_u_m_p
11.06.2005, 21:39
твой класс без данного бага в той форме как ты написал работать не будет!!!

потому что без данного бага твой метод доИмпорт получит лишь undefined

s_u_m_p
11.06.2005, 21:40
потом это это не баг, импорт классов происходит лишь после того как в глобале не оказалось соответствующих функций конструкторов

Nirth
11.06.2005, 21:43
мда и в правду, намудрил, можно извратиться и вызывать методы конечно, но тогда есть опасность что вызовем чего нить плохого, или ненужного

args [item][field]();

s_u_m_p
11.06.2005, 22:16
это баг, который возможно устранят. если ты посмотришь в код EventDispatcher'a то заметишь там такую строчку new EventDispatcher - без скобок, тоесть на данный момент, это работает, но по идее класс импортироваться не должен(а в друг у меня просто в глобале такие объекты есть?) так что если макромедия пофиксит данную фичу думаю такой вариант работать не будет
ИМХО.

по поводу new EventDispatcher:

f = function () {
this.walla = 'walla';
}
a = new f;

trace ('>>> ' + a.walla);

посмотри трайс

nuran
11.06.2005, 23:09
а вы о чём, ребята? =)

nuran
11.06.2005, 23:11
это баг, который возможно устранят. если ты посмотришь в код EventDispatcher'a то заметишь там такую строчку new EventDispatcher - без скобок, тоесть на данный момент, это работает, но по идее класс импортироваться не должен(а в друг у меня просто в глобале такие объекты есть?) так что если макромедия пофиксит данную фичу думаю такой вариант работать не будет
ИМХО.

Ты что, шутишь? =)

Nirth
11.06.2005, 23:19
f = function () {
this.walla = 'walla';
trace(this.walla);
}
new f;

s_u_m_p
12.06.2005, 00:00
f = function () {
this.walla = 'walla';
trace(this.walla);
}
new f;


и что ты этим хотел сказать?

Nirth
12.06.2005, 00:03
То что на данный момент, флэш по левому обрабатывает конструктор, и скорее всего это исправиться(очень на это надеюсь)

а что ты хотел сказать этим?

f = function () {
this.walla = 'walla';
}
a = new f;

trace ('>>> ' + a.walla);

s_u_m_p
12.06.2005, 00:23
То что на данный момент, флэш по левому обрабатывает конструктор, и скорее всего это исправиться(очень на это надеюсь)

а что ты хотел сказать этим?

f = function () {
this.walla = 'walla';
}
a = new f;

trace ('>>> ' + a.walla);


слушайте хватит гнать на флэш, а? а как должен обрабатывать оператор new??? что должен создаваться экземпляр класса а конструктор класс не запускаться при new f?

Nirth
12.06.2005, 00:29
в C# выдает ошибку если не поставить скобок, я поспрашивал пару программистов на C++ те тоже говорят что без скобок должна выдаваться ошибка, я не гоню.
я констатирую факт, что на данный момент AS слегонца багнутый :)
так же прикол в том, что private почему то работает как protected

nuran
12.06.2005, 00:59
в C# выдает ошибку если не поставить скобок, я поспрашивал пару программистов на C++ те тоже говорят что без скобок должна выдаваться ошибка, я не гоню.
я констатирую факт, что на данный момент AS слегонца багнутый :)
так же прикол в том, что private почему то работает как protected
Дарагой, ты только что узнал что AS это не C ? =) Поздравляю с открытием.

Nirth
12.06.2005, 01:01
нуран почитай пожалуйста спецификацию emca которую юзает флэш, а потом уже хохми.

nuran
12.06.2005, 01:13
нуран почитай пожалуйста спецификацию emca которую юзает флэш, а потом уже хохми.
Иди сам читай, и ищи кучу отличий.

nuran
12.06.2005, 01:21
нуран почитай пожалуйста спецификацию emca которую юзает флэш, а потом уже хохми.
Вот может в Flash 8 приблизят ещё больше к спецификации, но сейчас то бессмысленно (почти =) на неё ссылаться.

nuran
12.06.2005, 01:29
да, сорри, что-то резко выражаюсь =\

Nirth
12.06.2005, 01:30
Ткни ка пальцем, что то я не вижу чтоб не в ecma 262 не в ECMAScript 4 Draft Proposal, строчки где сказанно что объекты можно создавать юзая new но без скобок...