PDA

Просмотр полной версии : Как добавить динамическую переменную к DisplayObject без создания доп. класса


Universe
12.06.2012, 19:38
Мне нужно добавить моему DisplayObject динамическое свойство, например
someDispObj.someVar = 10;
как я могу это сделать без создания динамического класса?

КорДум
12.06.2012, 19:44
Никак. Зачем Вам такое понадобилось? Думаю, Вам нужно выделить этот ДО в отдельную сущность-класс.

XoJlToH
12.06.2012, 22:22
С мувиклипами такое точно проходит

MoHaX
12.06.2012, 22:58
Тебе нужен динамический класс, MovieClip подойдет, но вообще это не красиво.

expl
12.06.2012, 23:04
Там для кое-каких не MovieClip-ов тоже чудесным образом проходит, если во Flash IDE собирать, а потом, когда пытаеся заюзать Tween-овую либу, компилируя mxmlc и говоришь автору "Чувак, падает!". Автор делает каменное лицо и заявляет что у него все работает, а для не визуальных объектов твинер применить никогда не потребуется (http://lurkmore.to/640_%D0%BA%D0%B8%D0%BB%D0%BE%D0%B1%D0%B0%D0%B9%D1%82).

Если потребовалось что-то сохранить для объекта, но на нём самом этого делать не нужно/нельзя, то на ум приходят решения:

1. Меппинг значения в Dictionary - мепит та подсистема, которой нужны эти значения. Одно из достоинств - 2 подсистемы могут держать для объекта свои разные значения. Недостатки - куча кода, надо следить очень внимательно за добвалением и удалением.

2. Обертка, т.е. храним у себя в подсистеме не сами объекты, а объекты со свойтсвами и ссылкой на эти оригинальные объекты. За соответствием значений и объектов уследить проще, чем в первом случае, но эти обертки надо как-то добавлять и удалять в нашу подсистему.

3. Можно вообще везде таскать обертки вместо объектов, если есть возможность влезть во все места

4. Еще проще (если ограничения наследования не включатся) отнаследоваться и добавить поля и везде таскать наследника, если, опять же есть доступ во все части, где объекты используются.

Кстати, какая цель? Просто, я подозреваю, что для Вашей задачи есть решение гораздо красивше этих 4-х и не требующее никаких меппингов/списков/регистров этих объектов.

Universe
13.06.2012, 12:11
У меня есть объект, которому я добавляю некоторую функциональность с помощью статического метода другого класса. Чтото на подобии своего TweenLite. Допустим что я приеняю к объекту гравитацию. Затем где то в коде мне нужно будет определять есть на этом объекте гравитация или нет. Наиболее удобным вариантом, как мне кажется, является создание в моём объекте переменной isGravity, на которую я буду воздействовать вызывая статический метод. Но такое не прокатывает для всех типов DisplayObject. Может тогда завести в этом статическом классе массив, в который пушить объект на который применили гравитацию, а потом смотреть циклом в этот массив и определять есть ли такой объект в массиве?

udaaff
13.06.2012, 12:21
Создайте соответствующий интерфейс со свойством isGravity, который должны будут реализовать объекты, с которыми может работать ваш класс, и реализуйте его.
Или еще вариант. Создать дополлнительный "подкласс" в классе "менеджере" этих объектов, например, MyGravityObjectRegistration. Создавать экземпляр данного класса при добавлении объектов с графитацией, и в нём уже хранить ссылку на сам объект и дополнительные параметры.

Universe
13.06.2012, 12:35
как то не хотелось бы создавать отдельный класс, ради одного свойства. Для этого и использую в данном случае статический метод, вместо создания класса.

КорДум
13.06.2012, 12:52
Не экономьте байты. И место в листингах кода.

ChuwY
13.06.2012, 13:03
Можно провернуть вот такой изврат (исключительно ради изврата):


package {
import flash.display.Sprite;

public class tests extends Sprite {
private var _enemy : Unit = new Unit();
public function tests() {
var propName : String = 'foo';
traceProperty(_enemy, propName);//target don't contain prop 'foo'
addProperty(_enemy, 'foo', 'bar');
traceProperty(_enemy, propName);// bar
}

private function addProperty(target : Object, propName : String, defValue : *):void{
Object(target).constructor.prototype[propName] = defValue;
}

private function traceProperty(target : Object, propName : String):void{
try{
trace(target[propName]);
} catch(error : Error){
trace("target dont contain prop " + propName);
}
}
}
}

internal class Unit {
public function Unit() {
}
}

Inet_PC
13.06.2012, 15:01
ChuwY, Ваш способ сработает только для одного экземпляра Unit:

var n:Unit=new Unit();
traceProperty(n, propName);
//bar
Но если его немного доработать, то:
package
{
import flash.display.Sprite;
import flash.utils.Dictionary;

public class tests extends Sprite
{
public function tests()
{
var propName : String = 'isGravity';

var unit1:Unit = new Unit();
var unit2:Unit = new Unit();

trace(getProperty(unit1, propName));
trace(getProperty(unit2, propName));

setProperty(unit1, propName, true);

trace(getProperty(unit1, propName));
trace(getProperty(unit2, propName));

setProperty(unit2, propName, true);

trace(getProperty(unit1, propName));
trace(getProperty(unit2, propName));

setProperty(unit1, propName, null);
setProperty(unit2, propName, null);

trace(getProperty(unit1, propName));
trace(getProperty(unit2, propName));
}

public static function getProperty(target:Object, prop:String):Object
{
var properties:Dictionary = Object.prototype[prop] as Dictionary;
return properties ? properties[target] : null;
}

public static function setProperty(target:Object, prop:String, value:Object):void
{
var properties:Dictionary = Object.prototype[prop] as Dictionary;
if (!properties)
{
properties = new Dictionary(true);
Object.prototype[prop] = properties;
}

properties[target] = value;
}
}
}
internal class Unit {}
//null
//null
//true
//null
//true
//true
//null
//null

Можно еще deleteProp добавить по вкусу. И в словаре сохранять объект, тогда можно будет хранить сразу несколько свойств для одного экземпляра.
Вообще этот кусок кода достоен сами знаете какого сайта.
И в реальном проекте, я бы не стал так делать и Вам не советую!!!

ChuwY
13.06.2012, 15:24
ChuwY, Ваш способ сработает только для одного экземпляра Unit:


Вы не правы.

public function tests() {
var propName : String = 'foo';
traceProperty(_enemy, propName);//target don't contain prop 'foo'
addProperty(_enemy, 'foo', 'bar');
traceProperty(_enemy, propName);// bar
//
var unit2 : Unit = new Unit();
var unit3 : Unit = new Unit();
var unit4 : Unit = new Unit();
trace(unit2[propName]);//bar
trace(unit3[propName]);//bar
trace(unit4[propName]);//bar
addProperty(_enemy, 'foo', 'new value');
trace(unit2[propName]);//new value
trace(unit3[propName]);//new value
trace(unit4[propName]);//new value
}

Впрочем, не спорю с тем, что способ гхм... спорной ценности.

Inet_PC
13.06.2012, 15:32
Я походу не правильно выразился. Я имел в виду, что у любого экземпляра класса значение свойства будет одинаковым. Т.е. выставляя свойство оно будет выставлено для всех экземпляров этого класса. Фактически у Вас получилась статическая переменная, а у меня (через туже статическую переменную) не статическая. И соответственно в зависимости от того, что нужно ТС придется либо Ваш, либо мой (либо оба) способа использовать.

expl
13.06.2012, 18:05
У меня есть объект, которому я добавляю некоторую функциональность с помощью статического метода другого класса. Чтото на подобии своего TweenLite. Допустим что я приеняю к объекту гравитацию. Затем где то в коде мне нужно будет определять есть на этом объекте гравитация или нет. Наиболее удобным вариантом, как мне кажется, является создание в моём объекте переменной isGravity, на которую я буду воздействовать вызывая статический метод. Но такое не прокатывает для всех типов DisplayObject. Может тогда завести в этом статическом классе массив, в который пушить объект на который применили гравитацию, а потом смотреть циклом в этот массив и определять есть ли такой объект в массиве?
1. TweenLite работает на регистировании объектов в Dictionary
2. Спрашивать есть ли гравитация в этом случае будете у этого TweenLite
3. Если это не либа, которой придется работать с левым кодом - сделайте свой класс/интерфейс c нужными свойствами - ибо добавление их сверху и слежение за списком - это перебор
4. Можете, конечно, как ChuwY показал попробовать

Universe
16.06.2012, 23:29
всем спасибо) Заюзаю dictionary ))

dimarik
17.06.2012, 23:32
У меня есть объект, которому я добавляю некоторую функциональность с помощью статического метода другого класса. Чтото на подобии своего TweenLite. Допустим что я приеняю к объекту гравитацию. Затем где то в коде мне нужно будет определять есть на этом объекте гравитация или нет.

Это могут быть проблемы "подобия" TweenLite. Он должен создать дескриптор объекту, с которым работает (п. 2 пост No. 5 (http://www.flasher.ru/forum/showpost.php?p=1084384&postcount=5)). Обращайтесь к менеджеру с запросом "есть ли такой объект и сколько у него гравитации".

Но не факт. Я может быть где-то и в надклассе вставил. Сильно зависит от задачи.