Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Поиск рулит! Сообщения за день Все разделы прочитаны
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 07.01.2011, 13:51
djyamato вне форума Посмотреть профиль Отправить личное сообщение для djyamato Посетить домашнюю страницу djyamato Найти все сообщения от djyamato
  № 1  
Ответить с цитированием
djyamato
 
Аватар для djyamato

Регистрация: Feb 2006
Сообщений: 884
Записей в блоге: 2
Отправить сообщение для djyamato с помощью ICQ Отправить сообщение для djyamato с помощью Skype™
По умолчанию Почему Array так срабатывает ?

Здравствуйте, всех с прошедшими праздниками
Есть у меня код undo/redo
Сначала написал свой а затем взял из WYSIWYG редактора господ Merlin и Dimchansky класс History, в нем то же самое поведение массива

Добавляю итем в массив истории
При последовательном добавлении все нормально, новый элемент становится в конец массива
А если сделать несколько раз (или даже один раз) undo, новый элемент становится в предпоследнюю "ячейку" массива
Точнее даже сказать так:
После добавления в массив элемента я трэйсом вывожу этот массив, также и ПЕРЕД операцией добавления я вывожу его тоже трэйсом
А при нажатии на undo последующем действии (записывается новый итем истории) уже при выводе ДО добавления итема, основной массив УЖЕ содержит почему-то добавляемый элемент, причем он становится всегда в предпоследнюю "ячейку" массива
Черте что

Вот часть трэйса
Код:
добавление нового элемента: сейчас массив длиной в 2 pointer=2
Добавляемый элемент: matrix.a=1.175897479057312 matrix.b=-0.44668155908584595 matrix.c=0.44668155908584595
__historyStorage массив до изменения длины:
_step_ '0' matrix.a=1 matrix.b=0 matrix.c=0
_step_ '1' matrix.a=0.9348256587982178 matrix.b=-0.3551069498062134 matrix.c=0.3551069498062134
======================
__MainArray массив после изменения:
_step_ '0' matrix.a=1 matrix.b=0 matrix.c=0
_step_ '1' matrix.a=0.9348256587982178 matrix.b=-0.3551069498062134 matrix.c=0.3551069498062134
_step_ '2' matrix.a=1.175897479057312 matrix.b=-0.44668155908584595 matrix.c=0.44668155908584595

В массиве записаны 3 состояния

stepUp - Это UNDO

Отмотали на 1 назад


добавление нового элемента: сейчас массив длиной в 3 pointer=1
Добавляемый элемент: matrix.a=0.6870874762535095 matrix.b=0.7265746593475342 matrix.c=-0.7265746593475342

ОБРАТИТЕ ВНИМАНИЕ НА ЭЛЕМЕНТЫ МАССИВА ДО ЕГО ИЗМЕНЕНИЯ
СРАВНИТЕ ЭЛЕМЕНТЫ МАССИВОВ

__historyStorage массив до изменения длины:
_step_ '0' matrix.a=1 matrix.b=0 matrix.c=0
_step_ '1' matrix.a=0.68708749240745 matrix.b=0.7265746595673742 matrix.c=-0.7265746595673742
_step_ '2' matrix.a=1.175897479057312 matrix.b=-0.44668155908584595 matrix.c=0.44668155908584595

Добавляемый элемент "лезет" в предпоследнюю "ячейку" массива

CORRECTING...
======================
__MainArray массив после изменения:
_step_ '0' matrix.a=1 matrix.b=0 matrix.c=0
_step_ '1' matrix.a=0.6870874762535095 matrix.b=0.7265746593475342 matrix.c=-0.7265746593475342
Почему же так происходит ?
Вот код класса
Код AS3:
/**
* Класс с историей действий
*/
package div0.classes.history {
	import flash.events.*;
	import flash.display.MovieClip;
 
	public class History extends MovieClip{
 
		private var dataDonor:MovieClip;
		private var MainArray:Array=new Array();
 
 
		// глубина буфера истории
		private var historyDepth:uint;
		// массив, содержащий итемы истории
		private var historyStorage:Array=new Array();
		// указатель на текущее состояние в массиве истории
		private var pointer:int = 0;
		private var i:int;
 
		private var historyUnit:historyItem;
 
		private var UndoBtn:MovieClip;
		private var RedoBtn:MovieClip;
 
 
 
		public function History(depth:uint,undo:MovieClip,redo:MovieClip,dD:MovieClip):void{
			trace("parent="+parent);
			historyDepth = depth;
			UndoBtn=undo;
			RedoBtn=redo;
			dataDonor=dD;
			RedoBtn.disable();
			UndoBtn.disable();
		}
 
		// корректируем список redo, если до этого была операция отмены и были трансформации
		public function correct():void{
			trace("CORRECTING...");
			if ( emptyHistoryBuffer() && pointer != historyStorage.length) return;
			historyStorage = historyStorage.slice(0, pointer);
		}
 
		// добавляем в историю состояние 
		public function addHistoryItem():void{
			var AddItem:historyItem=new historyItem(dataDonor.picTransform,dataDonor.colorsTransform,Math.random());
			historyStorage=MainArray.concat();
			for(var t:int=0;t<historyStorage.length;t++){
				if(AddItem==historyStorage[t]){
					trace("добавляемый элемент уже существует !!!!");
				}
			}
 
 
			trace("\nдобавление нового элемента: сейчас массив длиной в "+historyStorage.length+" pointer="+pointer);
			trace("Добавляемый элемент: matrix.a="+AddItem.transformObject.matr.a+" matrix.b="+AddItem.transformObject.matr.b+" matrix.c="+AddItem.transformObject.matr.c);
			trace("__historyStorage массив до изменения длины:");
 
			for(i=0;i<historyStorage.length;i++){
				trace("_step_ '"+i+"' matrix.a="+historyStorage[i].transformObject.matr.a+" matrix.b="+historyStorage[i].transformObject.matr.b+" matrix.c="+historyStorage[i].transformObject.matr.c);
			}
 
			if ( !historyStorage ){
				historyStorage = new Array();
			}
			if (pointer != historyStorage.length){
				correct();
			}
			// если буфер истории полон, сдвигаем (выталкиваем) первые элементы и добавляем в конец новое состояние
			while ( historyStorage.length >= historyDepth ) {
				historyStorage.shift();
			}
 
			historyStorage.push(AddItem);
			//pointer=historyStorage.length;
			//historyStorage[pointer]=AddItem;
			MainArray=historyStorage.concat();
			pointer = historyStorage.length;
			RedoBtn.disable();
			UndoBtn.enable();
 
			trace("======================\n__MainArray массив после изменения:");
			for(var u:int=0;u<MainArray.length;u++){
				trace("_step_ '"+u+"' matrix.a="+MainArray[u].transformObject.matr.a+" matrix.b="+MainArray[u].transformObject.matr.b+" matrix.c="+MainArray[u].transformObject.matr.c);
			}
 
		}
 
		// отмена действия (undo)
		public function stepUp():historyItem{
			trace("stepUp");
			//trace("emptyHistoryBuffer()="+emptyHistoryBuffer());
			RedoBtn.enable();
			historyUnit=null;
			if (emptyHistoryBuffer()){
				return historyUnit;
			}
			if (pointer == historyStorage.length) {
				//addHistoryItem();
				pointer--;
			}
 
			if ( pointer-- <= 0){
				pointer = 0;
				UndoBtn.disable();
			}
			historyStorage=MainArray.concat();
			historyUnit = historyStorage[pointer];
			return historyUnit;
		}
 
		// повтор действия (redo)
		public function stepDown():historyItem{
			UndoBtn.enable();
			historyUnit=null;
			if ( emptyHistoryBuffer() ){
				return historyUnit;
			}
			if ( pointer++ >= (historyStorage.length - 1)) {
				pointer = historyStorage.length - 1;
				RedoBtn.disable();
			}else {
				historyStorage=MainArray.concat();
				historyUnit = historyStorage[pointer];
			}
			return historyUnit;
		}
 
		public function clearHistory():void{
			trace("CLEARING HISTORY");
			//historyArray=new Array();
			historyStorage.length
			RedoBtn.disable();
			UndoBtn.disable();
			pointer=0;
		}
 
 
		// проверка на существование массива действий
		private function emptyHistoryBuffer():Boolean{
			return ( !historyStorage || historyStorage.length == 0 );
		}
 
	}
}

Старый 07.01.2011, 14:36
Wolsh вне форума Посмотреть профиль Отправить личное сообщение для Wolsh Найти все сообщения от Wolsh
  № 2  
Ответить с цитированием
Wolsh
Нуб нубам
 
Аватар для Wolsh

модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
Не уверен, что точно понял все злоключения пойнтера, но может быть все же
Код AS3:
if ( --pointer <= 0){
    pointer = 0;
    UndoBtn.disable();
}
Добавлено через 4 минуты
Код AS3:
if ( pointer++ >= (historyStorage.length - 1)) {
соответственно тоже наоборот. Проверьте, это ли Вы хотели -
Код AS3:
var n:Number = 1;
trace( n-- <= 0); // false
var m:Number = 1;
trace( --m <= 0); // true
__________________
Reality.getBounds(this);

Старый 07.01.2011, 14:41
djyamato вне форума Посмотреть профиль Отправить личное сообщение для djyamato Посетить домашнюю страницу djyamato Найти все сообщения от djyamato
  № 3  
Ответить с цитированием
djyamato
 
Аватар для djyamato

Регистрация: Feb 2006
Сообщений: 884
Записей в блоге: 2
Отправить сообщение для djyamato с помощью ICQ Отправить сообщение для djyamato с помощью Skype™
Спасибо, попробую, но все-таки, кто же массив-то меняет, ДО его изменения в методе addHistoryItem() ?

Старый 07.01.2011, 16:00
Wolsh вне форума Посмотреть профиль Отправить личное сообщение для Wolsh Найти все сообщения от Wolsh
  № 4  
Ответить с цитированием
Wolsh
Нуб нубам
 
Аватар для Wolsh

модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
Цитата:
кто же массив-то меняет
Из Вашего лога не видно, что что-то меняется ДО.
Цитата:
Добавляемый элемент: matrix.a=0.6870874762535095 ...
Цитата:
ОБРАТИТЕ ВНИМАНИЕ НА ЭЛЕМЕНТЫ МАССИВА ДО ЕГО ИЗМЕНЕНИЯ
СРАВНИТЕ ЭЛЕМЕНТЫ МАССИВОВ

__historyStorage массив до изменения длины:
_step_ '0' matrix.a=1 matrix.b=0 matrix.c=0
_step_ '1' matrix.a=0.68708749240745 ....
_step_ '2' matrix.a=1.175897479057312 ...
__________________
Reality.getBounds(this);

Старый 07.01.2011, 16:11
djyamato вне форума Посмотреть профиль Отправить личное сообщение для djyamato Посетить домашнюю страницу djyamato Найти все сообщения от djyamato
  № 5  
Ответить с цитированием
djyamato
 
Аватар для djyamato

Регистрация: Feb 2006
Сообщений: 884
Записей в блоге: 2
Отправить сообщение для djyamato с помощью ICQ Отправить сообщение для djyamato с помощью Skype™
несовсем понятно там, извините

Вот массив после добавления итема в конец массива хистори (конечный вариант массива)
Код:
массив после изменения:
_step_ '0' matrix.a=1 matrix.b=0 matrix.c=0
_step_ '1' matrix.a=0.9348256587982178 matrix.b=-0.3551069498062134 matrix.c=0.3551069498062134
_step_ '2' matrix.a=1.175897479057312 matrix.b=-0.44668155908584595 matrix.c=0.44668155908584595
Затем нажали один раз на анду
И по идее, элементы массива, неисключенные, должны быть такими же как и у того, листинг которого выше, НО массив этот принимает вид вот какой (повторяюсь, это ДО изменения массива)

Код:
массив до изменения длины:
_step_ '0' matrix.a=1 matrix.b=0 matrix.c=0
_step_ '1' matrix.a=0.68708749240745 matrix.b=0.7265746595673742 matrix.c=-0.7265746595673742
_step_ '2' matrix.a=1.175897479057312 matrix.b=-0.44668155908584595 matrix.c=0.44668155908584595
Пришедший новый элемент массива :
Код:
Добавляемый элемент: matrix.a=0.6870874762535095 matrix.b=0.7265746593475342 matrix.c=-0.7265746593475342
То есть предпоследний элемент массива меняется на пришедший, ДО того, как какие-нибудь действия с массивом происходят,получается что так.


Последний раз редактировалось djyamato; 07.01.2011 в 16:16.
Старый 25.02.2011, 06:15
djyamato вне форума Посмотреть профиль Отправить личное сообщение для djyamato Посетить домашнюю страницу djyamato Найти все сообщения от djyamato
  № 6  
Ответить с цитированием
djyamato
 
Аватар для djyamato

Регистрация: Feb 2006
Сообщений: 884
Записей в блоге: 2
Отправить сообщение для djyamato с помощью ICQ Отправить сообщение для djyamato с помощью Skype™
Матрицы преобразования нужно было клонировать ! О как. Перестал глючить механизм

Создать новую тему Ответ Часовой пояс GMT +4, время: 02:55.
Быстрый переход
  « Предыдущая тема | Следующая тема »  
Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


Часовой пояс GMT +4, время: 02:55.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.