Hate
конь вакуумный
offline
Опыт:
43,137Активность: |
Darklight:
к тому что это очищает все данные на ячейке хэндла. Я хз зачем тебе выяснять есть ли такой хэндл (о_О) и что то делать, если тебе это для одного юнита, то все делается через глобалки, если же мультиприменение, то зачем находить родительский ключ? |
03.07.2012, 17:52 | #21
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Darklight
offline
Опыт:
976Активность: |
ScorpioT1000, Проверил. Да, ScorpioT1000, ты прав! Если юнит не разлагается, то сразу же как умирает (поистечение времени смерти в параметрах юнита) значение в ячейки Хеш таблицы сразу же принимает значение null. ТО есть, ссылки из Хеш таблицы не учитываются. Вернее, после проведения более точного эксперимента, значение юнита в Хеш таблице сразу же обнолвется на null (не очищается, а заменяется значением null) после обработки гибели юнита (если он не разлагается; для разлагающихся - это произойдёт после разложения; или при вызове функции RemoveUnit), приэтом я специально оставил ссылку на юнита в отдельной переменной - так вот там юнит стал "безымянным", но id сохранился - значит варик сам обрабатывает ячейки Хеш таблицы с уничтожаемыми объектами и присваивает им значение null, несмотря на то, что на эти объекты могу быть ссылки из других переменных. И это даже без вызова RemoveUnit
Значит операться на ссылки в хеш таблицах как на источники ключей нельзя :( придётся отдельно сохранять числовые ключи идентификаторов этих ссылок Ну, или использовать (там где можно) событие "Unit die" и обрабатывать умершего юнита до того как его ссылкав Хеш таблице превратится в null Вот такая вот засада вышла! Darklight добавил: Hatsume_Hate, естественно - я знаю про эту функцию - я ей очищаю когда нужно очистить. Но, вот, как выяснилось выше - еси в моёмс алгоритме срабатывает таймер, а юнит уже мёртв, то значение в ячекйи Хеш таблицы, таймера, где хранилась ссылка на этого юнита может стать null - и я не очищу данные, которые хранятся в ячейке самого юнита (под его идентификатором) - придётся организовывать перекрёстные ссылки на идентификаторах, а не на самих объектах. И, в общем, ещё много чего нужно учитывать. |
03.07.2012, 19:58 | #22
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Hate
конь вакуумный
offline
Опыт:
43,137Активность: |
как я уже писал выше - умер юнит - очистил его ключ. в таймере условие что юнит умер или время 0 -> очистить ключ хэндла таймера. Не понимаю о чем ты паришься. |
03.07.2012, 20:08 | #23
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
ScorpioT1000
Работаем
offline
Опыт: отключен
|
Мне кажется, надо это добавить куда-то как статью
ScorpioT1000 добавил:
добавлю в свою статью про типы данных =) ScorpioT1000 добавил:
xgm.ru/p/wc3/w3_data_types добавил Отредактировано ScorpioT1000, 03.07.2012 в 21:15. |
03.07.2012, 21:07 | #24
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Darklight
offline
Опыт:
976Активность: |
Hatsume_Hate:
Как я уже написал выше ;) для юнитов и разрушаемых объектов этот подход будет наиболее оптимальным. Но, что делать с объектами, у которых нет таких событий "умер"? Например, предметы? Надо будет попробовать провести эксперимент, что будет с ними, если хранить их в Хеш таблице и уничтожить. Если то же, что с юнитами, то операться на ссылки предметов как на источники ключей так же нельзя. И отследить их уничтожение тоже нельзя. Я создаю себе систему универсальной работы с Хеш таблицей и мне нужно учесть все нюансчы ;) Darklight добавил: ScorpioT1000: Как мне кажется - этот эксперимент нужно бы ещё раз потворить (на другой карте, компьютере и, желательно, другим человеком), чтобы исключить факторы "невероятности" ;) И поэкспериментировать над другими хэндловыми объектами - как будут вести себя они. Например - предметы. Тогда уже, сделав выводы это можно будет оформить в виде отдельной статейки, охватывающей всю суть "проблемы"! |
04.07.2012, 00:48 | #25
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
DioD
offline
Опыт:
45,134Активность: |
вводите сами себя в заблуждение малоизвестным фактом - юниты особенные, это единственные хендлы которые умирают сами по себе и очищаются сами по себе, как только юнит умер и разложился, его хендл автоматически удаляется, это невозможно остановить и контролировать.
если вы хотите проверять как оно вообще, юниты не подходят (как и любые другие производные виджета) |
04.07.2012, 10:28 | #26
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
ScorpioT1000
Работаем
offline
Опыт: отключен
|
Как слился, начал себе же противоречить лол
|
04.07.2012, 11:34 | #27
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Darklight
offline
Опыт:
976Активность: |
DioD, Вот оно как - но тем не менее - как я уже сказал выше - работа ссылки на убитого юнита из Хеш таблицы и из обычной переменной всё равно разная!.
А по остальным объектам я как раз написал, что нужно бы поэкспериментировать. Я предложил попробовать с предметом, но, тип item тоже от widget произведён - значит в Хеш таблице так же должен очиститься при разрушении (тут только проблема с отсутвующим событием типа "Item die").
Все, умирающие объекты произведены от widget. Можно, например попробовать location или group - сохранить их в Хеш таблице и уничтожить програмно - и посмотреть, что будет со ссылокй в на этот объект в Хеш таблице и её идентификатором хэндла. |
04.07.2012, 11:42 | #28
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
ScorpioT1000
Работаем
offline
Опыт: отключен
|
То же самое, там всё банально |
04.07.2012, 11:50 | #29
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
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 | #30
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
DioD
offline
Опыт:
45,134Активность: |
что-то не так, в документации к хеш таблицам было прямо прописано самими близзами что хеш таблица держит указатель на объект и этот указатель учитывается мусоркой.
только проверялось это иначе, таймер сохранялся в хеш таблицу потом удалялся и локальная переменная освобождалась, после чего айди таймера никому не доставался до тех пор пока существовало поле в хеш таблице |
04.07.2012, 15:07 | #31
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Darklight
offline
Опыт:
976Активность: |
DioD:
Я разве как-то не так тест провёл. У меня как раз с таймером есть вариант с удерживающей переменной - так вот даже она не удерживает Хеш таблицу от самоизменения ячейки хранения объекта на значение null. Код я привёл. Смотрите. Повторяйте. Анализируйте. Если будет что сказать - пишите. |
04.07.2012, 15:20 | #32
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
DioD
offline
Опыт:
45,134Активность: |
она и будет ссылаться на объект который null потому что он удалён, а айди этого объекта никому другому не назначается. |
05.07.2012, 17:03 | #33
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Darklight
offline
Опыт:
976Активность: |
DioD, Что-то я Вас не понял. Я написл, что при разрушении (удалении) объекта - если на него есть ссылка из переменной, то она останется, не будет возвращать null, и будет иметь id). При этом, если на этот объект будет ссылка из ячейки Хеш таблицы, то её значение заменится на null и не будет иметь id. Получаем совершенно иное поведение хранения значений в Хеш таблице, которое нужно учитывать. Отсюда следствие - операться на объектные значения в Хеш таблице, как на ключи (источники id), нельзя - т.к. как только этот объект будет уничтожен - его id будет потерян (в Хеш таблице). Это очень важное замечание. Но очищать Хеш таблицу всё же надо - т.к. ячекйа по-порежнему будет занята (будет хранить значение null). И это никак не зависит от типа объекта, т.е. unit, item и прочий производный widget здесь не причём - все обрабатывается одинаково! |
06.07.2012, 08:54 | #34
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
J64_
offline
Опыт:
4,724Активность: |
Darklight:
Имел ввиду:
Когда все записываемые в хеш\массивы хэндлы будут контролироваться через структуры, проблема Диода полностью отпадёт, ведь при смерти мы приравняем указатель на хэндл структуры к null, а в хеш\массивы будем записывать только указатель структуры//, а он, интежер.
Можно конечно извратиться на чистом джасе, но, так будет неудобно. |
06.07.2012, 21:54 | #35
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
ScorpioT1000
Работаем
offline
Опыт: отключен
|
Judycaster64 имеет ввиду заменить хеш стеком структур. |
06.07.2012, 22:15 | #36
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Darklight
offline
Опыт:
976Активность: |
ScorpioT1000, Скорее не заменить хеши, а сделать прослойку - обёртку над хэндлами. Это, в какой-томере поможет, но накладых расъодов будет много. Я уже переделал у себя код, в Хеш таблице наряду со значением хэндлового объекта в отдельной ячейке храню его id (в Хеш таблице это не проблема) и использую его - когда мне нужна адресация по id. Это уде третья версия реализации библиоткеи для работы с Хеш таблицей. Любоптыно, что первая была практически такой же ;) А структуры, они сдесь лдишние, если кончено весь остальной код не построен на их использовании. |
12.07.2012, 11:42 | #37
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|