XGM Forum
Сайт - Статьи - Проекты - Ресурсы - Блоги

Форуме в режиме ТОЛЬКО ЧТЕНИЕ. Вы можете задать вопросы в Q/A на сайте, либо создать свой проект или ресурс.
Вернуться   XGM Forum > Warcraft> Академия: форум для вопросов
Ник
Пароль
Войти через VK в один клик
Сайт использует только имя.

Ответ
 
Hate
конь вакуумный
offline
Опыт: 43,033
Активность:
Darklight:
Hatsume_Hate:
FlushChildHashtable( hash, key)
Это к чему было сказано?
к тому что это очищает все данные на ячейке хэндла. Я хз зачем тебе выяснять есть ли такой хэндл (о_О) и что то делать, если тебе это для одного юнита, то все делается через глобалки, если же мультиприменение, то зачем находить родительский ключ?
Старый 03.07.2012, 17:52
Darklight

offline
Опыт: 976
Активность:
ScorpioT1000, Проверил. Да, ScorpioT1000, ты прав! Если юнит не разлагается, то сразу же как умирает (поистечение времени смерти в параметрах юнита) значение в ячейки Хеш таблицы сразу же принимает значение null. ТО есть, ссылки из Хеш таблицы не учитываются. Вернее, после проведения более точного эксперимента, значение юнита в Хеш таблице сразу же обнолвется на null (не очищается, а заменяется значением null) после обработки гибели юнита (если он не разлагается; для разлагающихся - это произойдёт после разложения; или при вызове функции RemoveUnit), приэтом я специально оставил ссылку на юнита в отдельной переменной - так вот там юнит стал "безымянным", но id сохранился - значит варик сам обрабатывает ячейки Хеш таблицы с уничтожаемыми объектами и присваивает им значение null, несмотря на то, что на эти объекты могу быть ссылки из других переменных. И это даже без вызова RemoveUnit
Значит операться на ссылки в хеш таблицах как на источники ключей нельзя :( придётся отдельно сохранять числовые ключи идентификаторов этих ссылок
Ну, или использовать (там где можно) событие "Unit die" и обрабатывать умершего юнита до того как его ссылкав Хеш таблице превратится в null
Вот такая вот засада вышла!
Darklight добавил:
Hatsume_Hate, естественно - я знаю про эту функцию - я ей очищаю когда нужно очистить. Но, вот, как выяснилось выше - еси в моёмс алгоритме срабатывает таймер, а юнит уже мёртв, то значение в ячекйи Хеш таблицы, таймера, где хранилась ссылка на этого юнита может стать null - и я не очищу данные, которые хранятся в ячейке самого юнита (под его идентификатором) - придётся организовывать перекрёстные ссылки на идентификаторах, а не на самих объектах. И, в общем, ещё много чего нужно учитывать.
Старый 03.07.2012, 19:58
Hate
конь вакуумный
offline
Опыт: 43,033
Активность:
как я уже писал выше - умер юнит - очистил его ключ.
в таймере условие что юнит умер или время 0 -> очистить ключ хэндла таймера. Не понимаю о чем ты паришься.
Старый 03.07.2012, 20:08
ScorpioT1000
Работаем
offline
Опыт: отключен
Мне кажется, надо это добавить куда-то как статью
ScorpioT1000 добавил:
добавлю в свою статью про типы данных =)
ScorpioT1000 добавил:

Отредактировано ScorpioT1000, 03.07.2012 в 21:15.
Старый 03.07.2012, 21:07
Darklight

offline
Опыт: 976
Активность:
Hatsume_Hate:
как я уже писал выше - умер юнит - очистил его ключ.
Как я уже написал выше ;) для юнитов и разрушаемых объектов этот подход будет наиболее оптимальным. Но, что делать с объектами, у которых нет таких событий "умер"? Например, предметы? Надо будет попробовать провести эксперимент, что будет с ними, если хранить их в Хеш таблице и уничтожить. Если то же, что с юнитами, то операться на ссылки предметов как на источники ключей так же нельзя. И отследить их уничтожение тоже нельзя.
Я создаю себе систему универсальной работы с Хеш таблицей и мне нужно учесть все нюансчы ;)
Darklight добавил:
ScorpioT1000:
Мне кажется, надо это добавить куда-то как статью
Как мне кажется - этот эксперимент нужно бы ещё раз потворить (на другой карте, компьютере и, желательно, другим человеком), чтобы исключить факторы "невероятности" ;)
И поэкспериментировать над другими хэндловыми объектами - как будут вести себя они. Например - предметы. Тогда уже, сделав выводы это можно будет оформить в виде отдельной статейки, охватывающей всю суть "проблемы"!
Старый 04.07.2012, 00:48
DioD

offline
Опыт: 45,134
Активность:
вводите сами себя в заблуждение малоизвестным фактом - юниты особенные, это единственные хендлы которые умирают сами по себе и очищаются сами по себе, как только юнит умер и разложился, его хендл автоматически удаляется, это невозможно остановить и контролировать.
если вы хотите проверять как оно вообще, юниты не подходят (как и любые другие производные виджета)
Старый 04.07.2012, 10:28
ScorpioT1000
Работаем
offline
Опыт: отключен
Как слился, начал себе же противоречить лол
хештаблица учитывается GC, если ссылка на объект есть в хештаблице объект никогда не освободится.
о каком объекте идет речь? destroy уничтожает данные мгновенно, далее объект становится "пустым" - почти все функции работы с ним возвращают фейлд, при этом хендл висит в памяти
Старый 04.07.2012, 11:34
Darklight

offline
Опыт: 976
Активность:
DioD, Вот оно как - но тем не менее - как я уже сказал выше - работа ссылки на убитого юнита из Хеш таблицы и из обычной переменной всё равно разная!.
А по остальным объектам я как раз написал, что нужно бы поэкспериментировать. Я предложил попробовать с предметом, но, тип item тоже от widget произведён - значит в Хеш таблице так же должен очиститься при разрушении (тут только проблема с отсутвующим событием типа "Item die").
Все, умирающие объекты произведены от widget.
Можно, например попробовать location или group - сохранить их в Хеш таблице и уничтожить програмно - и посмотреть, что будет со ссылокй в на этот объект в Хеш таблице и её идентификатором хэндла.
Старый 04.07.2012, 11:42
ScorpioT1000
Работаем
offline
Опыт: отключен
То же самое, там всё банально
Старый 04.07.2012, 11:50
Darklight

offline
Опыт: 976
Активность:
DioD, Проверил Предмет, Группу, Таймер - всё в Хеш таблице отрабатывает одинаково - после удаления объекта в его ячейку в Хеш таблице заносится значение null, а если хранить объект в переменной - то хендл с ней сохраняется (вместе с исходным идентификатором хендла, хотя сам объект более не существует).
Код:
((кат
((код jass
function Trig_ggg_Actions takes nothing returns nothing
local timer t
local unit u
set udg_hash = InitHashtable()

call SaveUnitHandle(udg_hash, 1, 0, CreateUnit(Player(14),'hpea',0,0,0))
set u = CreateUnit(Player(14),'hpea',0,0,0)
call SaveUnitHandle(udg_hash, 1, 0, u)
BJDebugMsg("Unit ="+GetUnitName(LoadUnitHandle(udg_hash, 1, 0))+" id="+I2S(GetHandleId(LoadUnitHandle(udg_hash, 1, 0))))
BJDebugMsg("u name="+GetUnitName(u)+" code="+I2S(GetUnitTypeId(u))+" id="+I2S(GetHandleId(u)))
call KillUnit(LoadUnitHandle(udg_hash, 1, 0))
call RemoveUnit(LoadUnitHandle(udg_hash, 1, 0))
call PolledWait(1.0)
BJDebugMsg("Unit ="+GetUnitName(LoadUnitHandle(udg_hash, 1, 0))+" id="+I2S(GetHandleId(LoadUnitHandle(udg_hash, 1, 0))))
if LoadUnitHandle(udg_hash, 1, 0) == null then
BJDebugMsg("Unit is NULL")
endif
if u == null then
BJDebugMsg("u is NULL")
else
BJDebugMsg("u name="+GetUnitName(u)+" code="+I2S(GetUnitTypeId(u))+" id="+I2S(GetHandleId(u)))
endif

call SaveItemHandle(udg_hash, 1, 0, CreateItem('spsh', GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit())))
BJDebugMsg("Item ="+GetItemName(LoadItemHandle(udg_hash, 1, 0))+" id="+I2S(GetHandleId(LoadItemHandle(udg_hash, 1, 0))))
call RemoveItem(LoadItemHandle(udg_hash, 1, 0))
call PolledWait(1.0)
BJDebugMsg("Item ="+GetItemName(LoadItemHandle(udg_hash, 1, 0))+" id="+I2S(GetHandleId(LoadItemHandle(udg_hash, 1, 0))))

call SaveGroupHandle(udg_hash, 1, 0, CreateGroup())
BJDebugMsg("Group id="+I2S(GetHandleId(LoadGroupHandle(udg_hash, 1, 0))))
call DestroyGroup(LoadGroupHandle(udg_hash, 1, 0))
call PolledWait(1.0)
BJDebugMsg("Group id="+I2S(GetHandleId(LoadGroupHandle(udg_hash, 1, 0))))

call SaveTimerHandle(udg_hash, 1, 0, CreateTimer())
set t = CreateTimer()
call SaveTimerHandle(udg_hash, 1, 0, t)
BJDebugMsg("Timer id="+I2S(GetHandleId(LoadTimerHandle(udg_hash, 1, 0))))
call DestroyTimer(LoadTimerHandle(udg_hash, 1, 0))
call PolledWait(1.0)
BJDebugMsg("Timer id="+I2S(GetHandleId(LoadTimerHandle(udg_hash, 1, 0))))
if LoadTimerHandle(udg_hash, 1, 0) == null then
BJDebugMsg("Timer is NULL")
endif
if t == null then
BJDebugMsg("t is NULL")
else
BJDebugMsg("t id="+I2S(GetHandleId(t)))
endif
endfunction
))
))
Результат:
Unit =Работник id=1048677
u name=Работник code=1752196449 id=1048677
Unit = id=0
Unit is NULL
u name= code=0 id=1048677
Item =Амулет Защиты id=1048679
Item = id=0
Group id=1048681
Group id=0
Timer id=1048682
Timer id=0
Timer is NULL
t id=1048682
Старый 04.07.2012, 13:04
DioD

offline
Опыт: 45,134
Активность:
что-то не так, в документации к хеш таблицам было прямо прописано самими близзами что хеш таблица держит указатель на объект и этот указатель учитывается мусоркой.
только проверялось это иначе, таймер сохранялся в хеш таблицу потом удалялся и локальная переменная освобождалась, после чего айди таймера никому не доставался до тех пор пока существовало поле в хеш таблице
Старый 04.07.2012, 15:07
Darklight

offline
Опыт: 976
Активность:
DioD:
только проверялось это иначе, таймер сохранялся в хеш таблицу потом удалялся и локальная переменная освобождалась, после чего айди таймера никому не доставался до тех пор пока существовало поле в хеш таблице
Я разве как-то не так тест провёл. У меня как раз с таймером есть вариант с удерживающей переменной - так вот даже она не удерживает Хеш таблицу от самоизменения ячейки хранения объекта на значение null. Код я привёл. Смотрите. Повторяйте. Анализируйте. Если будет что сказать - пишите.
Старый 04.07.2012, 15:20
DioD

offline
Опыт: 45,134
Активность:
она и будет ссылаться на объект который null потому что он удалён, а айди этого объекта никому другому не назначается.
Старый 05.07.2012, 17:03
Darklight

offline
Опыт: 976
Активность:
DioD, Что-то я Вас не понял. Я написл, что при разрушении (удалении) объекта - если на него есть ссылка из переменной, то она останется, не будет возвращать null, и будет иметь id). При этом, если на этот объект будет ссылка из ячейки Хеш таблицы, то её значение заменится на null и не будет иметь id. Получаем совершенно иное поведение хранения значений в Хеш таблице, которое нужно учитывать. Отсюда следствие - операться на объектные значения в Хеш таблице, как на ключи (источники id), нельзя - т.к. как только этот объект будет уничтожен - его id будет потерян (в Хеш таблице). Это очень важное замечание. Но очищать Хеш таблицу всё же надо - т.к. ячекйа по-порежнему будет занята (будет хранить значение null).
И это никак не зависит от типа объекта, т.е. unit, item и прочий производный widget здесь не причём - все обрабатывается одинаково!
Старый 06.07.2012, 08:54
J64_

offline
Опыт: 4,724
Активность:
Darklight:
Judycaster64, Что за структуру Вы имеете в виду? Я, в данном проекте, не использую vJass/cJass, да и там, насколько я знаю, структуры - это лишь обёртки над массивами и они не имеют хэндла.
Имел ввиду:
	struct myUnitStructure
	{
		unit u;
		...
		int field1;
		...
	};
	...
	struct myItemStructure
	{
		item i;
		...
	};
Когда все записываемые в хеш\массивы хэндлы будут контролироваться через структуры, проблема Диода полностью отпадёт, ведь при смерти мы приравняем указатель на хэндл структуры к null, а в хеш\массивы будем записывать только указатель структуры//, а он, интежер.
Можно конечно извратиться на чистом джасе, но, так будет неудобно.
Старый 06.07.2012, 21:54
ScorpioT1000
Работаем
offline
Опыт: отключен
Judycaster64 имеет ввиду заменить хеш стеком структур.
Старый 06.07.2012, 22:15
Darklight

offline
Опыт: 976
Активность:
ScorpioT1000, Скорее не заменить хеши, а сделать прослойку - обёртку над хэндлами. Это, в какой-томере поможет, но накладых расъодов будет много. Я уже переделал у себя код, в Хеш таблице наряду со значением хэндлового объекта в отдельной ячейке храню его id (в Хеш таблице это не проблема) и использую его - когда мне нужна адресация по id. Это уде третья версия реализации библиоткеи для работы с Хеш таблицей. Любоптыно, что первая была практически такой же ;)
А структуры, они сдесь лдишние, если кончено весь остальной код не построен на их использовании.
Старый 12.07.2012, 11:42
Ответ

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск

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

BB-коды Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход



Часовой пояс GMT +3, время: 05:37.