Darklight
offline
Опыт:
976Активность: |
Вызов GetHandleId у удалённого объекта
Что будет, если вызвыать функцию GetHandleId(hndl) у переменной, ссылающейся на объект, который был уже удалён (переменной значение null не присваивалось)? Значение будет отличным от вызова данной функции у неудалённого объекта? Есть ли какая-нибудь разница, если это ссылка была получена из хештаблицы? |
01.07.2012, 15:37 | #1
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Lipen
offline
Опыт:
1,550Активность: |
Разве так трудно проверить?
» Тык
|
01.07.2012, 15:53 | #2
+1/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
DioD
offline
Опыт:
45,134Активность: |
объект высвобождается не мгновенно (иногда), цикл внутреннего GC работает по фазе луны. |
01.07.2012, 18:16 | #3
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Darklight
offline
Опыт:
976Активность: |
Lipen, Простите, вы, кажется, не поняли суть вопроса. А суть была вот в чём:
|
01.07.2012, 18:33 | #4
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
DioD
offline
Опыт:
45,134Активность: |
хештаблица учитывается GC, если ссылка на объект есть в хештаблице объект никогда не освободится. |
01.07.2012, 19:26 | #5
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Darklight
offline
Опыт:
976Активность: |
DioD, Всё понял, спасибо. |
01.07.2012, 20:19 | #6
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
ScorpioT1000
Работаем
offline
Опыт: отключен
|
о каком объекте идет речь? destroy уничтожает данные мгновенно, далее объект становится "пустым" - почти все функции работы с ним возвращают фейлд, при этом хендл висит в памяти |
01.07.2012, 20:48 | #7
+1/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Vadik29
Choice Battle 1.6а
offline
Опыт:
15,845Активность: |
Иногда вызов пустой функции приводит к полной остановке процесса, а в тяжелых случаях бывает десинх или крит. |
01.07.2012, 21:05 | #8
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Darklight
offline
Опыт:
976Активность: |
ScorpioT1000, Речь шла только про хэндл.
Если я буду помещать в хеш сам объект (юнит или таймер), то спустя некоторое время мне нужно будет к нему обратиться. Так вот, мне нужен будет ID его хэндла и факт того, что объект ещё жив или уничтожен, чтобы выполнить сервисные функции (например, по очистке данных в хештаблицах по этому объекту, в случае его гибели). Если такой подход не надёжен, придётся вставлять скрипт очистки по смерти воина (хотя это не всегда годится, т.к. некоторые, скажем, способности, ещё некоторое время должны "висеть над трупом" - но это, конечно решается; то же и с разрушаемым объектом), а вот с таймером уже сложнее (нельзя отследить момент его разрушения, правда это можно сделать только программно - значит тоже решается).
А вот, что делать, например, с предметом? Если к нему привязаны данные в хештаблицах, то как корректно определить, что предмета больше нет и данные необходимо очистить? Сохранять ссылку на предмет в связке с числовым ID её хэндла и сверять по периодическому таймеру?
А в хештаблице могу сохраняться и другие объектные типы, что с ними? |
02.07.2012, 19:53 | #9
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
prog
offline
Опыт:
32,865Активность: |
Darklight, советую пересмотреть структуру того что ты делаешь. Что бы там ни говорили, хештаблицы достаточно быстро работают, но все-же не стоит ими злоупотреблять, делая каждый чих с их использованием. Если не можешь проконтролировать жизненный цикл объекта, не используй его хендл как ключ в таблице. |
02.07.2012, 21:22 | #10
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
J64_
offline
Опыт:
4,724Активность: |
как решение можно сделать структуру с хэндлом этого объекта, и использовать в качестве ключа\индекса структуру. |
03.07.2012, 04:51 | #11
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
ScorpioT1000
Работаем
offline
Опыт: отключен
|
проверять существование юнита так GetUnitTypeId(u) > 0 итема GetItemTypeId(u) > 0
ScorpioT1000 добавил: + к этим проверкам добавлять and IsUnitAlive (ну это не точно так, но суть ясна), если мертвые тоже не нужны |
03.07.2012, 13:02 | #12
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Darklight
offline
Опыт:
976Активность: |
prog, Тогда, прошу дать совет. Сейчас подход такой:
У юнита(ов) обрабатывается какое-либо триггерное заклинание (или аура, или автоприменение/автоподбор целей), действующее во времени - тогда я:
Тогда - таймер, срабатывая, получает по своему идентификатору все необходимые данные и проверяем "жизнь" юнита-владельца - если он мертв - завершает свою работу и стартует очистку Хеш данных, связанных с таймером и с юнитом.
Когда юнита - производит управление - то по идентификатору юнита и второго ключа (идентификатора заклинания) получается ссылка на таймер - по идентификатору этого таймера получаются данные заклинания из Хеш таблицы и команда управления обрабатывается. По необходимости таймер уничтожается и данные в Хеше по нему очищаются.
Отдельно - можно обработать подписку на смерь юнита - тогда по идентификатору юнита и перечню идентификаторов заклинаний этого юнита в качестве второго ключа получаются ссылки на таймеры, таймеры уничтожаются, по идентификаторам этих таймеров очищаются данные в Хеш таблице. В конце очищаются данные в Хеш таблице по самому юниту.
В принципе, у одного заклинание может быть несколько таймеров - они прописываются под идентификатором юнита в Хеш таблице под разными вторичными ключами.
Итого получается двойная ссылка в Хеш таблице. Под идентификатором таймера лежат данные и ссылка на юнита-владельца. Под идентификатором юнита и идентификатором видов заклинаний (второй ключ) лежат ссылки на таймеры, которые относятся к этим заклинаниям. Нужный источник выбирается в зависимости от обращений - из события таймера или из события юнита.
Естественно для заклинаний, не имеющих управления со стороны юнита с момента своего начала выполнения (люього вида), связь из юнит->таймер не нужна, но лично сейчас у меня все триггерные заклинания получаются с управлением ;)
Всё слишком сложно? Есть более простое решение?
А, ведь, я пока говорил только про заклинания и юнитов/разрушаемые объекты, а ведь с предеметами хуже - там отследить их "гибель" сложнее! Judycaster64, Что за структуру Вы имеете в виду? Я, в данном проекте, не использую vJass/cJass, да и там, насколько я знаю, структуры - это лишь обёртки над массивами и они не имеют хэндла.
А так, то я, конечно, могу сохранять не только ссылки на таймеры/юнитов но и их идентификаторы. Мой вопрос был как раз в том, стоит ли не стоит так делать. Сначала я дела Хеш таблицы, сохраняя перекрестные ссылки в виде числовых идентификаторов. Потом переделал на объектные ссылки и... задался этим вопросом. |
03.07.2012, 13:29 | #13
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Hate
конь вакуумный
offline
Опыт:
43,030Активность: |
что то не понятно чего ты добиваешься, есть мнение что ты сам придумал себе сложности.
умер юнит -> очистил все на его ключе
тикает таймер/>условия что юнит умер -> очистил все на его ключе непонятно что ты там придумал |
03.07.2012, 13:37 | #14
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Darklight
offline
Опыт:
976Активность: |
Hatsume_Hate, Ок. Привожу пример. Имею заклинаний с нестандартным автоприменением. Поиск цели, для применения заклинания, осуществляется триггерно:
1. Беру, например, базовую абилку “Acrs” (Проклятие). 2. Отлавливаю команду начала автоприменения “curseon” (событие юнита). 3. Проверяю ячейку в Хеш таблице по идентификатору юнита (первый ключ) и идентификатором заклинания (второй ключ: StringHash(“My super ability autousing timer”)) на наличие значения через функцию HaveSavedHandle. 4. Если значение есть – значит таймер уже запущен – ничего делать не нужно. 5. Если значения нет - запускаю таймер заклинания, который ищет подходящие цели и, когда находит отдаёт юниту-владельцу приказ “curse” на найденную цель (далее отрабатывает триггер данного приказа и к делу это уже не относится). Таймер помещаю в Хеш таблицу под идентификатором созданного таймера. 6. В ячейку этого идентификатора помещаю ссылку на юнита-владельца (чтобы получить того, кому нужно будет отдать приказ для применение заклинания на цель). 7. Под идентификатором юнита (первый ключ) и идентификатором заклинания (второй ключ: StringHash(“My super ability autousing timer”)) помещаю ссылку на таймер. 8. Событие таймера. Таймер на каждой своей итерации получает из Хеш таблицы юнита-владельца (по идентификатору таймера) - caster . 9. Проверяю полученного юнита на то, что он уже мёртв (GetWidgetLife(caster)<0.405) 10. Если мёртв, то останавливаю таймер, очищаю в Хештаблице данные по идентификатору таймера и удаляю значение в ячейке под идентификатором юнита (первый ключ) и идентификатором заклинания (второй ключ: 0StringHash(“My super ability autousing timer”)) через RemoveSavedHandle, уничтожаю таймер. 11. Если юнит жив, то ищу цель (target) в области нахождения этого юнита, и когда её нахожу, выполняю команду IssueTargetOrder(caster, “curse”, target)**. 12. Отлавливаю команду окончания автоприменения “curseoff” (событие юнита). 13. По идентификатору юнита (первый ключ) и идентификатору заклинания (второй ключ: StringHash(“My super ability autousing timer”)) получаю ссылку на таймер. 14. Останавливаю и уничтожаю таймер. 15. Очищаю в Хештаблице данные по идентификатору таймера и удаляю значение в ячейке под идентификатором юнита (первый ключ) и идентификатором заклинания (второй ключ: StringHash(“My super ability autousing timer”)) через RemoveSavedHandle. 16. Отлавливаю команду окончания автоприменения “curse” (событие юнита). 17. Обрабатываю необходимые действия – применяю заклинание на цель. 18. НЕОБЯЗАТЕЛЬНО. Отлавливаю событие “Unit die” (событие юнита). 19. Проверяю ячейку в Хеш таблице по идентификатору юнита (первый ключ) и идентификатором заклинания (второй ключ: StringHash(“My super ability autousing timer”)) на наличие значения через функцию HaveSavedHandle. 20. Если значения нет – значит таймер не запущен (автоприменение не включено) – ничего делать не нужно. 21. Если значение есть – то, по идентификатору юнита (первый ключ) и идентификатору заклинания (второй ключ: StringHash(“My super ability autousing timer”)) получаю ссылку на таймер. 22. Останавливаю и уничтожаю таймер. 23. Очищаю в Хеш таблице данные по идентификатору таймера и удаляю значение в ячейке под идентификатором юнита (первый ключ) и идентификатором заклинания (второй ключ: StringHash(“My super ability autousing timer”)) через RemoveSavedHandle. Как-то вот так получается. Простой алгоритм обработки автоприменения заклинания. В данном случае целевого заклинания, но это не важно. Я в чём-то не прав? Darklight добавил: ScorpioT1000: Вот это и была суть вопроса:
|
03.07.2012, 14:56 | #15
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
ScorpioT1000
Работаем
offline
Опыт: отключен
|
Откуда такая информация? |
03.07.2012, 15:09 | #16
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Darklight
offline
Опыт:
976Активность: |
ScorpioT1000:
отсюда (пост выше) DioD: что - не так? |
03.07.2012, 15:30 | #17
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Hate
конь вакуумный
offline
Опыт:
43,030Активность: |
|
03.07.2012, 15:46 | #18
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
ScorpioT1000
Работаем
offline
Опыт: отключен
|
кароче попробуй сохранить в хт, убить юнита, заремувить его и проверить через время GetUnitTypeId при этом время разложение дб равно нулю, иначе он действительно будет висеть целиком |
03.07.2012, 16:18 | #19
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Darklight
offline
Опыт:
976Активность: |
Hatsume_Hate:
Это к чему было сказано? |
03.07.2012, 17:51 | #20
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|