Перейти к содержанию

Дайджесты за январь-февраль

Обновления гайдов и аддонов

Январь Февраль

Мониторинг серверов и редактор аддонов

Представляем вам две легенды. То, о чем можно было только мечтать, стало реальностью.

Мониторинг серверов Редактор аддонов

Подсказки из игры на вашем сайте

Теперь вы можете отображать сведения о внутриигровых элементах простым наведением курсора мыши.

Подробнее

Апдейтер аддонов

Представляем вам программу для автообновления аддонов и делимся подробностями.

Подробнее Скачать

ramirez

Разработчик аддонов
  • Постов

    224
  • Зарегистрирован

  • Посещение

Весь контент ramirez

  1. Нэ. Распишу подробней, но с конца. Quote: По факту выполнения одно и тоже, но по факту чтения второй вариант менее удобен для восприятия особено если челоек не знаком с структурой работы библиотеки Если пишешь стихи, то, как минимум, должен знать буквы. Если не смотреть в TWidget, то тоже, в общем, хрен чем попользуешься. В отличие от SetPlacementPlain по TWidget вообще никакой документации нет. Quote: Ну а у меня в классе ты где увидел 8мь методов для установки размера ? 3 метода ... Остальные ты не написал. Это SetPositionHigh, SetAlignX, SetAlignY, SetSizingX, SetSizingY. Не говоря о геттерах, типа забытого GetPosition. Пока библиотекой пользуешься ты один - канает. Но если претендуешь на повсеместное использование библиотеки всеми, тогда - полный функционал. Разработчики из Нивала придумали структуру plain placement не потому, что такие мудаки, а потому что так было нужно. Она полностью описывает позиционирование виджета на экране, включая все случаи изменения разрешения экрана и размеров виджетов. Обертки SetWidth и т.п. не затрагивают и четверти этого функционала. В моем случае можно написать одной строчкой: Code: widgetlibrary.SetPlacementPlain( widget, { sizeX = 480, sizeY = 100, posX = 100, posY = 100, highPosY = 53, alignY = WIDGET_ALIGN_BOTH } ) В твоем - облом. А особенно удобно placement генерить, хранить и передавать в другие функции агрументом. Например, в случае драг'н'дропа логичные и читабельные обертки SetWidth, SetPosition и т.п. бесполезны. Quote: Выбрать тот или иной подход - это просто дело вкуса, кто то любит ООП подход, кто то поклоник структурного программирования. Универсализация узконаправленных действи - это как раз ненужное усложнение. Вкус в этом деле - вреден. "Узко направлять", оборачивая изначально работающие механизмы из соображений вкуса, - см. выше. Quote: Узконаправленный - да но "грамоздкий и сырой" - это то в чем появляеться ? Я не понимаю как узконаправленное дествие которое относиться к 1-му типа данных можно ( нужно ? ) делать универсальным ? Есть виджет и есть дествия над ним узконапрвленные, имеющие смысл лишь в приложении к типу виджет - есть 2 варианта автоматизации - писать класс обертку или писать набор функций. Только 2 варианта? А можно совсем заместить виджеты своими объектами и делать с ними что угодно, например. И обертка, и библиотека сразу будет. Громоздкий - ибо толпа ненужных функций. Не нужны: Code: GetChildByName -> widget:GetChildUnchecked( name, recursive )GetChildByIndex -> widget:GetNamedChildren() [ ChildIndex ] SetColor -> widget:SetBackgroundColor( color ) GetChildCount -> GetTableSize( widget:GetNamedChildren() ) Hide -> Show( false ) ShowAllChild, HideAllChild -> parent:Show( bVisible ) CreateNewObjectByDesc, GetDesc -> в нивальских старых скриптах есть фабрика виджетов с полным функционалом. SetPosition со-товарищи - см. выше. Что осталось? Сырой - это недописанный. Везде используется if self.Widget then, но при этом львиная доля стандартных методов виджетов не обернута. Если их предполагалось использовать как WidgetTable.Widget:<имя метода>( агрументы ) без проверки, то на кой это все было вообще городить? Да и поддержка хреновой горы оберток при постоянно меняющемся API никогда не даст дописать. И по-прежнему не вижу обещанных классов. Сырой - криво написанный. GetChildByName через GetNamedChildren и цикл с условием - шедевр. GetChildByIndex через такой же цикл, но с рукопашным итератором - еще более шедевр. Индусы рыдают. =) Распил Show на Show и Hide, и при этом совмещенные в MakeMovable DNDReg и DNDUnreg. Прочие мелочи, вроде забытых переменных в ShowAllChild и общих грамматических ошибок. Про вынужденно прикрученный сбоку драгНдроп - ваще отдельная песня. Я понимаю - незнание Lua, практик программирования, нехватка времени и т.д. Но ведь и не гонит никто вроде бы, не заставляет сразу писать библиотеку для всех. Вот так, блин, - всего-то хотел советов накидать, а в результате вынужден гнобить. =) P.S. Вот написал бы кто отлаженный TableToString, цены б ему не было. Можно даже награду объявить.
  2. Quote: ппц *)))) Ты денги что ли рубить собрался на своих наработках, для АО *)))). С чего ты взял, что они для AO? =) Они вообще. Потратил пару лет, если чо. А нивальское всем доступно, декомпилируй и вперед. Quote: Эмм а я как бы не говорил - "давай сгребем все в 1 файл" *)))) Двумя постами выше говорил: Quote: Их нада собрать, вылезать, отладить, стандартизировать, обьеденить в один подключаемый файл. Quote: А чем мой текущий то не правльный ? Твой текущий - правильный, но сильно узконаправленный, громоздкий и сырой. Quote: Дело тут в том что я получаю обьект типа userdata ниваловский и например если я хочу изменить размер то я вынуждет писать столбик кода... Ты походу и не понял, о чем я. А твой пример без TWidget решается так: Code: local function clone( t, o ) for k, v in pairs( t ) do o [ k ] = v end return o end function widgetlibrary.SetPlacementPlain( widget, placement ) widget:SetPlacementPlain( clone( placement, widget:GetPlacementPlain() ) ) end -------------------------------------------------------------------------------- -- Использование: local widget = parent:GetChildChecked( "widgetName", true ) widgetlibrary.SetPlacementPlain( widget, { sizeX = 480, posX = 64 } ) Вроде так же получилось, только оберток нет никаких, и метод один вместо восьми. А если хочется круто, то про прокси-таблички я выше писал.
  3. Quote: Да я тоже нашел это в скриптах. Вообщем-то Луа язык не строгий и как говориться "за ухом можно почесаться 175 способами" *))) Lua действительно многими вещами не заморачивается, и не предназначен для написания больших серьезных приложений. Поэтому надо быть осторожнее в планах. Наилучший способ - не городить ненужного. А если городить - то уж выбрать из 175 способов наиболее эффективный и наименее громоздкий, и его использовать. Quote: По сути измениться лишь способ обьявления. Можно так как я реализовал, можно так как делает это Нивал. Нет, это на порядок более универсальное расширение, чем TWidget, который предназначен исключительно для виджетов, и не годится, к примеру, для написания класса Vector3, чтоб удобно и быстро было работать с позициями юнитов в мире. Quote: В действительности же нужно наращивать функциональные возможности библиотеки. Вот например кто то приводил пример универсальной функции установки текста - помоему это был ты Ramirez - ну так взял бы и доработал этот моент в рамках билиотеки добавил бы новый класс или в уже существуюший TWidget. Наращивать надо с умом. У виджетов и так дофига всяких методов работы с ними, зачем нужны обертки для работы с их потомками? Возьми ссылку на самого потомка и работай непосредственно с ним. Дорабатывать в функции нечего, просто бери и пользуйся, как хочешь. Прелесть Lua как раз в том, что она без изменений может быть и методом TWidget и просто функцией библиотеки утилит. Quote: Просто разные "автоматизации" кода встречаютсья отрывочно то в одном то в другом аддоне. Их нада собрать, вылезать, отладить, стандартизировать, обьеденить в один подключаемый файл. Думаю не нужно говорить что как это упростит разработку как нам самим так и новым модмейкерам *) "Всех их вместе соберу..." =) Если собрать вместе в одном файле, то это не упростит, а усложнит разработку. И напротив, если расширения будут маленькими и независимыми друг от друга, и будут поставляться в пакете файлов, то разработчик сможет подключать только то, что ему действительно нужно, не заморачиваясь остальным. Вот тогда - действительно упростит. Quote: Ведь согласиль удобно просто сказать виджету - ты перетаскиваемый и не пареться как имено он перетаскиваеться и сохраняет свои позиции после релога. Соглашусь. А еще лучше - чтоб виджет мог таскать не только себя, но и любой другой указанный виджет, и не только таскать, но и менять его размер. Но для этого надо написать безглючную функцию SetRealRect, которая может пригодиться в милилионе других мест. Это - правильный пример расширения. Quote: Вот вопрос на засыпку - возможноли прикреплять разные реакции к однотипным ( созданным по 1му Desc-у ) обектам ? Нет, реакции переобзывать нельзя, если ты об этом. Зато можно менять имя виджета. В параметрах реакций есть поле sender, каковое - имя пославшего реакцию виджета. Дальше в обработчике смотришь на это имя и определяешь, что с ним делать. Quote: Button1.OnClick = Func1, а Button2.OnClick = Func2, хотя оба созданны по типу Button. Отвечает капитан Очевидность: Ну, для того, чтоб виджету добавить метод, нужно чтоб тип виджета в Lua был не "userdata", а "table". Других путей нет. TWidget вроде как раз этим и занимается, так что тебе по идее видней, как его надстраивать. Но регистрировать все равно придется, хотя бы на инициализации. Quote: Any ideas how do it ? *)))) Идеи - пожалуйста! =) 1. Сделать скрипт, автоматически пробегающийся по всему дереву виджетов и подменяющий их прокси-табличками, с выведенными наружу методами-обертками от исходных виджетов. Ключ к успеху - метатаблицы и widget:GetNamedChildren(). 2. Написать базовый класс виджета для этих прокси-табличек, в котором залудить функционал автоматической регистрации объявленных в классах-наследниках обработчиков реакций. Ну и ивентов заодно. =) 3. Всякий там ДрагнДроп, универсальные фукции для текстов и прочее реализовывать в классах-наследниках, разработав для этого единую архитектуру наследования. Quote: Ramirez - ты вроде постами выше намекал на то что чета придумал с обработчиками, не скупись делись если есть чем ! Дополни библиотеку или приведи пример и я сам дополню. Наработки на халяву не раздаю, о чем писал выше. У местных умельцев уже есть на руках всё, чем пользуется Нивал. Который, кстати, с их помощью лихо нафигачил весь стандартный интерфейс, весьма немаленький и непростой. Не видел, чтоб кто-то делился. Дополнять библиотеку, которой не пользуюсь и считаю в целом сомнительной, - ну, мы с Valltron'ом уже писали здесь про это, без обид.
  4. Пошарил тут в древних скриптах разрабов и извлек, предварительно почистив. Получилось забавно: Code: --------------------------------------------------------------------------------do local function mergemetatable( tab, mt ) local _mt = getmetatable( tab ) _mt = type( _mt ) == "table" and _mt or {} for k, v in mt do _mt [ k ] = v end setmetatable( tab, _mt ) return tab end ------------------------------------------------------------------------------ local function replicate( cl, obj ) return mergemetatable( obj or {}, { __index = cl } ) end ------------------------------------------------------------------------------ function Class( name, proto ) Global( name, mergemetatable( proto or {}, { __call = replicate, __name = name } ) ) end end -------------------------------------------------------------------------------- Что это дает? Это дает нам единственную глобальную функцию Class, которая позволяет объявить любую таблицу с набором свойств и методов "классом". Code: local base = { a = 2 }function base:GetA() return self.a end Class( "CBaseObject", base ) Что дает нам такой "класс"? Он позволяет плодить объекты, имеющие прототипом это самый класс. Code: local object = { a = 5 }CBaseObject( object ) LogInfo( "a = ", object:GetA() ) -- << a = 5 Можно написать и суперсжато, все равно пример выглядит по-идиотски =): Code: LogInfo( "a = ", CBaseObject{ a = 5 }:GetA() ) -- << a = 5 Будет работать и вот такое: Code: LogInfo( "a = ", CBaseObject{ b = 5 }:GetA() ) -- << a = 2 ибо в случае, когда свойство "a" не определено непосредственно в объекте, оно будет добыто из прототипа base, как значение по умолчанию. В такие "объекты" вдобавок можно постфактум напихать миллион всего, что может пригодиться - всяких свойств, методов и пр., то есть они легко расширяются и дополняются. Еще можно от такого класса наследоваться. Code: local child = CBaseObject{ a = 12, b = 4, c = 8 }function child:GetB() return self.b end function child:GetC() return self.c end Class( "CBaseChild", child ) То есть, берем и тупо объявляем классом расширенный и дополненный "объект класса" CBaseObject. На его основе также можно настрогать объектов. Code: local childobject = CBaseChild{ c = 108 }LogInfo( "a = ",childobject:GetA() ) -- << a = 12 LogInfo( "b = ",childobject:GetB() ) -- << b = 4 LogInfo( "c = ", childobject:GetC() ) -- << c = 108 Советую внимательно присмотреться на предмет развития библиотеки.
  5. Ну раз не задета, будем жить. Quote: 1. можно и НЕСКОЛЬКО, но в "промышленном" подходе несколько обработчиков тоже в лоб в таблицу не убихаеш однако. Зачем в одну-то? Суть нескольких как раз в том, чтоб их в разных случаях использовать. Если же в одном, то проще один обработчик писать. Quote: 2. аналог - добавление таблиц при необходимости уловия и/или нескольких обработчиков. Только таблицу добавишь один раз максимум, и то не факт, как практика показывает, а вот с отдельными обработчиками париться надо по жизни. Quote: 4. ну там вроде написанно что оно излишне переусложнено, но зато даёт максимум универсализации, там по сути вообще помнить ничего не надо, 1 таблица, 1 функция регистрации, единая структура для всех обработчиков. Не дает. Это не универсально, трудно расширяемо, условия в таком виде в реальных условиях неприменимы, + приходится помнить, как вся эта жесть устроена, чтоб продолжать ей пользоваться. Quote: 6. можно попросить пример? ну что-нибудь на подобии выше рассмотренных, простенький такой, не для 38ми скриптов с 4,5к строк, а для среднего по размерам аддона который в разы меньше, думаю это вы и без меня понимаете. Все расширения тоже написаны на Луа, а на халяву раздавать собственные наработки не готов. И в маленьком примере все эти расширения бессмысленны, без них быстрее и проще. Если вкратце, то в базовом классе заведена обвязка для метода-генератора пачки собственных обработчиков для каждого объекта, сам метод переопределяется в классах-наследниках и вызывается в теле widget:Show( bool ) для регистрации или отписки от событий. В основных скриптах только определяешь обработчики и все. Код обработчика пишется только однажды, а работает в 48 местах сразу. Фактически, это развитие идеи "промышленного" подхода; не фонтан, но хватает с головой. Quote: все подсказки я увидел и о чудо, вы будете удивленны, но даже проверил. я попытался донести мысль что скорее всего не для всех скриптов по размеру будет выгоден и нагляден этот подход, да и всего-лишь в первом своём посте, дальше лиш уточнял, видно не савсем удачно раз меня недопоняли. Если бы проверил в деле, не писал бы отвлеченной ерунды. В аддона среднего/большого размера - очень выгоден. В аддоне, реагирующем на одно событие - совсем не нужен. Quote: вот они собсветнно самостоятельно и учатся(а некоторые на них срываются ;-) ), только мне вот непонятно зачем изобретать велосипед самому если можно обсудить уже готовый чужой и учесть его возможные недостатки? Да, давайте поспорим о вкусе устриц с теми, кто их ел. =)
  6. Да, это замена стандартного интерфейса своим, насколько это возможно. Это дьявольски интересно(с).
  7. Отлично, честь задета, диалог налажен. =) Quote: 0. ну про ИМХО я не буду ничего говорить, угрюмому бородатому дядьке это уже сложно видно осознавать. да и как вы нащитали 3/33... ааааа, подождите да вы обьявление каждого регистратора за отдельный пунк считали... ну ниче так... мне понравилось :-))) 0. Объявление каждого ОБРАБОТЧИКА, а не регистратора. Неважно, придумал имя, или скопировал, все равно их надо вписывать/вставлять по одному в каждую регистрацию в отличие от. Потому и посчитал, это дополнительные имена, которых могло и не быть. Quote: 1. Надо ПРИДУМАТЬ а потом помнить имена хэндлеров - чем вам не подходят вашиже указанные "САМИ ИМЕНА ИВЕНТОВ, скопированные из предоставленного разрабами МАНУАЛА" 1. На один ивент можно порегистрировать НЕСКОЛЬКО обработчиков, одним именем ивента не обойдешься в это случае, надо придумывать. Да и называть глобальную функцию как константу - себя же запутывать. Quote: 2. Надо помнить, где регистрировали каждый из них. После определения нового хэндлера добро пожаловать "скроллить весь код" - всмысле номера строчек понить? воспринимать строчку "(хендрел, эвент)" нинаучили? 2. Нет, в смысле идти туда, где порегистрировано остальное и руками добавлять еще регистрацию. Quote: 3. ну при сложложной структуре будет у вас 5-10 таблиц по условиям которые тоже фиг знает как называть :-) 3. Не имею привычки усложнять себе жизнь, на практике больше трех не нужно было ни разу, а потом вообще отказался от этого. Quote: 4. это уже про сарказм. а что плохо во "втором варианте" ???, я когото учил гдето чемуто? мнения от поучений суровым дядькам отличать некогда, бороду надо причесывать? 4. Он ненужно переусложнен, этот вариант, и дальнейшее его развитие стремительно приводит к ценному пушному зверю. Если что-то пишешь на форуме, тем самым делишься с людьми, показываешь, что написанное может быть полезно собеседникам. Если это не так, зачем писал, ради "здесь был вася"? Quote: 5. Мат часть? таблицы в луа? основной механизм полноценной жизни? ну я канечно не уверен, вам там виднее, но мне кажется что адресат шутку вполне адыкватно воспринял, в отличае от вас. 5. Адресат - молодец, но дед Оккам его страсти не одобрил бы. Матчасть, да. И да, про Lua мне виднее. Quote: 6. если вы не полюзуетесь ни одним из этих подходов, просветите дитей жаждущих знаний чем вы пользуетесь? 6. Головой. А также объектами, псевдо-классами, множественным наследованием, кастомизируемыми виджетами и контроллером эффектов. Quote: З.Ы. как то вы агрессивно настроены, бороду подполили случайно али еще какой казус случился? Боже сделай чтобы люди до 10 считать научились перед тем как браузер запустить. - Я был агрессивен, это факт. Но по делу, считаю. Тут хором все подсказывают, где Вы ошибаетесь в своем мнении, но как-то это упорно игнорируется. Вот, попробовал на пальцАх показать. Quote: З.Ы.Ы. проще в работе это по мне так после 50ти строк регистраций, но чтото не видел я пока таких аддончиков, ведь "промышленный" он на то и промышленный или у вас дома студия и производство "луа аддонов для аллодов" на потоке стоит, да еще и таких что все по 1к строк да с переподвыподвертами :-) - В моем аддоне 38 файлов скрипта, суммарно 4.5к строк, выверты не практикую. И выкладывать пока не планирую. Quote: ушол учить матчаст, ток вы не подскажите чего? логики, математики, проектирования, программирования, луа... - Дети, жаждущие знаний - учатся самостоятельно. Обычно тому, чего жаждут.
  8. Эх, раз все ж пошла такая пьянка, держите меня семеро... =) Так вот, чтобы не быть, блин, ГОЛОСЛОВНЫМИ, проведем-ка подробный анализ обоих "подходов" (готовьтесь много и с чувством читать). Итак, "простой" метод разработчиков: Code: --------------------------------------------------------------------------------function OnEventСложноеИмяЭвентаНомерРаз( params ) --... -- тело хэндлера --... end -------------------------------------------------------------------------------- function OnEventИмяЭвентаЕщеСложнееНомерДва( params ) --... -- тело хэндлера --... end -------------------------------------------------------------------------------- function OnEventСовсемНечитаемоеИмяЭвентаНомерТри( params ) --... -- тело хэндлера --... end -------------------------------------------------------------------------------- function OnEventНеИмяАКакаяТоДракулаНомерЧетыре( params ) --... -- тело хэндлера --... end -------------------------------------------------------------------------------- --... --... еще ДВАДЦАТЬ ШЕСТЬ таких определений функций --... -------------------------------------------------------------------------------- function OnEventЯУжеОпухЭтоПисатьНомерТридцатьОдин( params ) --... -- тело хэндлера --... end -------------------------------------------------------------------------------- -- теперь пытаемся с этим всем взлететь -------------------------------------------------------------------------------- function ShowAddon( visible ) -- пример регистрации по условию addonPanel:Show( visible ) --... какая-то часть функции --... if visible then common.RegisterEventHandler( OnEventСложноеИмяЭвентаНомерРаз, "EVENT_СЛОЖНОЕ_ИМЯ_ЭВЕНТА_НОМЕР_РАЗ" ) common.RegisterEventHandler( OnEventИмяЭвентаЕщеСложнееНомерДва, "EVENT_ИМЯ_ЭВЕНТА_ЕЩЕ_СЛОЖНЕЕ_НОМЕР_ДВА" ) common.RegisterEventHandler( OnEventСовсемНечитаемоеИмяЭвентаНомерТри, "EVENT_СОВСЕМ_НЕЧИТАЕМОЕ_ИМЯ_ЭВЕНТА_НОМЕР_ТРИ" ) common.RegisterEventHandler( OnEventНеИмяАКакаяТоДракулаНомерЧетыре, "EVENT_НЕ_ИМЯ_А_КАКАЯ_ТО_ДРАКУЛА_НОМЕР_ЧЕТЫРЕ" ) common.RegisterEventHandler( OnEvent..., "..._НОМЕР_ПЯТЬ" ) common.RegisterEventHandler( OnEvent..., "..._НОМЕР_ШЕСТЬ" ) common.RegisterEventHandler( OnEvent..., "..._НОМЕР_СЕМЬ" ) --... --... ЕЩЕ ДЕВЯТЬ ТАКИХ ЖЕ РЕГИСТРАЦИЙ ХЭНДЛЕРОВ --... common.RegisterEventHandler( OnEvent..., "..._НОМЕР_СЕМНАДЦАТЬ" ) else common.UnRegisterEventHandler( OnEventСложноеИмяЭвентаНомерРаз, "EVENT_СЛОЖНОЕ_ИМЯ_ЭВЕНТА_НОМЕР_РАЗ" ) common.UnRegisterEventHandler( OnEventИмяЭвентаЕщеСложнееНомерДва, "EVENT_ИМЯ_ЭВЕНТА_ЕЩЕ_СЛОЖНЕЕ_НОМЕР_ДВА" ) common.UnRegisterEventHandler( OnEventСовсемНечитаемоеИмяЭвентаНомерТри, "EVENT_СОВСЕМ_НЕЧИТАЕМОЕ_ИМЯ_ЭВЕНТА_НОМЕР_ТРИ" ) common.UnRegisterEventHandler( OnEventНеИмяАКакаяТоДракулаНомерЧетыре, "EVENT_НЕ_ИМЯ_А_КАКАЯ_ТО_ДРАКУЛА_НОМЕР_ЧЕТЫРЕ" ) common.UnRegisterEventHandler( OnEvent..., "..._НОМЕР_ПЯТЬ" ) common.UnRegisterEventHandler( OnEvent..., "..._НОМЕР_ШЕСТЬ" ) common.UnRegisterEventHandler( OnEvent..., "..._НОМЕР_СЕМЬ" ) --... --... ЕЩЕ ДЕВЯТЬ ТАКИХ ЖЕ АНРЕГИСТРАЦИЙ ХЭНДЛЕРОВ --... common.RegisterEventHandler( OnEvent..., "..._НОМЕР_СЕМНАДЦАТЬ" ) end --... --... остальная часть функции end -- неплохих размеров простыня копипаста получилась, внимательно см. -------------------------------------------------------------------------------- --... --... Какой-то вспомогательный код, всегда есть --... -------------------------------------------------------------------------------- function Init() --... какая-то часть функции Инита --... common.RegisterEventHandler( OnEvent..., "..._НОМЕР_ВОСЕМНАДЦАТЬ" ) common.RegisterEventHandler( OnEvent..., "..._НОМЕР_ДЕВЯТНАДЦАТЬ" ) common.RegisterEventHandler( OnEvent..., "..._НОМЕР_ДВАДЦАТЬ" ) common.RegisterEventHandler( OnEvent..., "..._НОМЕР_ДВАДЦАТЬ_ОДИН" ) common.RegisterEventHandler( OnEvent..., "..._НОМЕР_ДВАДЦАТЬ_ДВА" ) --... --... ЕЩЕ ВОСЕМЬ ТАКИХ ЖЕ РЕГИСТРАЦИЙ ХЭНДЛЕРОВ --... common.RegisterEventHandler( OnEventЯУжеОпухЭтоПисатьНомерТридцатьОдин, "EVENT_Я_УЖЕ_ОПУХ_ЭТО_ПИСАТЬ_НОМЕР_ТРИДЦАТЬ_ОДИН" ) --... --... остальная часть Инита end -- еще одна простыня поменьше -------------------------------------------------------------------------------- Init() -- Наконец-то! -------------------------------------------------------------------------------- Теперь считаем пальцем, сколько всего нужно помнить, чтоб добавить сюда еще один ивент-хэндлер: Надо ПРИДУМАТЬ а потом помнить имена хэндлеров(код-стандарт обязывает): OnEventСложноеИмяЭвентаНомерРазOnEventИмяЭвентаЕщеСложнееНомерДваOnEventСовсемНечитаемоеИмяЭвентаНомерТриOnEventНеИмяАКакаяТоДракулаНомерЧетыре...еще 26 подобных имен...OnEventЯУжеОпухЭтоПисатьНомерТридцатьОдин Надо помнить, где регистрировали каждый из них. После определения нового хэндлера добро пожаловать "скроллить весь код"( в два разных места ) чтоб скопипастить регистрацию и для него тоже; и ОЧЕНЬ легко забыть это сделать. А потом мучительно охреневать, почему свеженаписанное не работает.Итого помнить: 33 пункта + легкий общий геморрой. Теперь "промышленный" метод разработчиков: Code: --------------------------------------------------------------------------------Global( "baseEvents", {} ) Global( "eventsOnDemand", {} ) -------------------------------------------------------------------------------- function baseEvents.СКОПИРОВАННОЕ_ИЗ_АПИ_РЕФЕРЕНСА_ИМЯ_ЕВЕНТА_НОМЕР_ОДИН( params ) --... -- тело хэндлера --... end -------------------------------------------------------------------------------- function baseEvents.СКОПИРОВАННОЕ_ИЗ_АПИ_РЕФЕРЕНСА_ИМЯ_ЕВЕНТА_НОМЕР_ДВА( params ) --... -- тело хэндлера --... end -------------------------------------------------------------------------------- --... --... Еще пятнадцать таких же определений --... -------------------------------------------------------------------------------- function eventsOnDemand.СКОПИРОВАННОЕ_ИЗ_АПИ_РЕФЕРЕНСА_ИМЯ_ЕВЕНТА_НОМЕР_ВОСЕМНАДЦАТЬ( params ) --... -- тело хэндлера --... end -------------------------------------------------------------------------------- function eventsOnDemand.СКОПИРОВАННОЕ_ИЗ_АПИ_РЕФЕРЕНСА_ИМЯ_ЕВЕНТА_НОМЕР_ДЕВЯТНАДЦАТЬ( params ) --... -- тело хэндлера --... end -------------------------------------------------------------------------------- --... --... Еще одиннадцать таких же определений --... -------------------------------------------------------------------------------- function eventsOnDemand.СКОПИРОВАННОЕ_ИЗ_АПИ_РЕФЕРЕНСА_ИМЯ_ЕВЕНТА_НОМЕР_ТРИДЦАТЬ_ОДИН( params ) --... -- тело хэндлера --... end -------------------------------------------------------------------------------- -- теперь активация аддона -------------------------------------------------------------------------------- function ShowAddon( visible ) -- пример регистрации по условию addonPanel:Show( visible ) --... какая-то часть функции --... if visible then RegisterEventHandlers( eventsOnDemand ) else UnRegisterEventHandlers( eventsOnDemand ) end --... --... остальная часть функции end -------------------------------------------------------------------------------- --... --... Какой-то вспомогательный код, который всегда есть --... Среди него затерялось ОДНАЖДЫ ОБЪЯВЛЕННОЕ вот это -------------------------------------------------------------------------------- function RegisterEventHandlers( handlers ) for event, handler in handlers do common.RegisterEventHandler( handler, event ) end end -------------------------------------------------------------------------------- function UnRegisterEventHandlers( handlers ) for event, handler in handlers do common.UnRegisterEventHandler( handler, event ) end end -------------------------------------------------------------------------------- --... -------------------------------------------------------------------------------- function Init() -- Теперь инициализация --... какая-то часть функции Инита --... RegisterEventHandlers( baseEvents ) --... --... остальная часть Инита end -------------------------------------------------------------------------------- Init() -------------------------------------------------------------------------------- Опять считаем пальцем, сколько нужно помнить: Именовать хэндлеры не нужно, именами им служат САМИ ИМЕНА ИВЕНТОВ, скопированные из предоставленного разрабами МАНУАЛА. Нужно помнить только имена таблиц baseEvents eventsOnDemandдабы их использовать при добавлении новых хэндлеров. При этом И ЕЖУ понятно, что "регистрация по условию" - это про eventsOnDemand, а постоянно работают - baseEvents. Пожалуй, это момент стоит тоже запомнить - +1. Где регистрировали, помнить не надо, там никогда ничего не меняется. После определения нового хэндлера "скроллить" к регистрации не нужно, FOR..EACH-цикл( который никто никогда и не видел ) все сделает сам. Итого помнить: 3 пункта. ТРИ! И принцип действия, как у ракет с тепловым наведением - объявил и забыл. Результаты партии: 3 против 33. "Помнить" надо в 11 раз МЕНЬШЕ. Это еще без намеренно не упомянутых реакций виджетов. Вот уж, воистину, "оптимизация ради оптимизации". Об "оторванных кусках реализации" можно смело забыть, что Вы там менять-то собрались так часто, и зачем? А теперь сарказм ( я предупреждал, держите меня ): Специально для детей, которым обязательно нужно лопатить код, чтоб посмотреть, что же там именно вызывается по условию, угрюмые бородатые дядьки придумали - внимание! - ИМЕНА ПЕРЕМЕННЫХ, прошу любить, жаловать и пользоваться. Помогает. А для детей, внезапно обнаруживших на своей мышке колесико, которое, о чудо! - можно крутить, не менее бородатые, но гораздо более лютые дядьки придумали быстрый поиск по коду, без которого ни один программер вообще не живет. А вот кручение колесика для него - ночной кошмар и предмет необоримой лени. Можно попытаться еще что-то поговорить, но приведенный Вами выше "второй вариант" говорит сам за себя очень отчетливо. Он бессмысленный и беспощадный(с), как всякий ценный пушной зверь песец. Никакие "ЗЫИМХО" этого не скрывают. Вот уж точно - "не умеешь сам - научи другого!". Боже, сделай так, чтоб всякий тут пишущий хотя бы разбирался в предмете. P.S. Таблицы в Lua - основной механизм полноценной жизни, и только в последнюю очередь "универсальные хранилища данных". НЕ ИМХО, учите матчасть. P.P.S. К слову, сам уже не пользуюсь ни одним из этих "подходов" и не вижу в них никакой сакральной ценности. Просто "промышленный" ОЧЕВИДНО проще в работе. Надеюсь, что приведенное подробное разъяснение уж закроет тему.
  9. Я верю практическому опыту; с досужими рассуждениями - в сад, это просто потеря времени. "2 события и 1 реакция по условию, +10 вспомогательных функций..." - дикие глупости. P.S. Про объявления речи не было, читайте внимательней и не пишите ерунды.
  10. А кто мешает объявить несколько таблиц, и одну из них регистрировать по условию? Это ничего не усложняет. Подход хороший, позволяет группировать ивент-хэндлеры и оперировать не отдельными хэндлерами, а сразу группами. И не надо идиотскую копипаст-простыню регистраций писать, сам факт наличия хэндлера гарантирует, что он пойдет в дело. Хотя все равно, даже погруппированная свалка кучи хэндлеров, по которым тонким слоем размазана логика разных частей аддона - остается свалкой, и ориентироваться в ней можно только пока скрипт небольшой. Хочется сказать: люди! =) Больше пользуйтесь таблицами, в них скрыта главная Луашная сила, это ж без пяти минут динамические объекты. Ну и поменьше глобальных переменных - они бессмысленны, только путаются где не положено и нэймспейс засоряют. =)
  11. Вообще в доках описан метод DestroyWidget. /LuaApi/FunctionWidgetDestroyWidget.html Так что, наверное, все-таки можно.
  12. Инициатива похвальная, круто. Но только исполнение пока излишне большое, дырявое и тем самым малоэффективное. Без обид, ты сам попросил поучаствовать. Нарожать оберток можно вагон, но их потом менеджить запаришься, да и не нужны они по-хорошему. В Lua вообще приветствуется подход "меньше кода = меньше ошибок". Так что, не очень понял цель этого скрипта. Группировать виджеты? А почему бы просто в таблицу не сложить? Вывод в лог ошибок? А как ловить ошибки в самой обертке? И так и не вкурил, причем здесь слово "класс". Про дыры: У любых созданных динамически виджетов родитель всегда mainForm, так что добавление в "контейнер" byDesc выглядит странно. Репликацию объектов через клонирование таблиц делать не рекомендуется, можно легко самому себе жизнь испортить, и никакая диагностика не спасет. Кстати, подумай, что будет при клонировании, если таблица ссылается хотя бы сама на себя, или на одну из своих частей, опыт сильно пригодится. Попробуй клонировать _G ради прикола. Хранить детей в специальной таблице "дети" и соорудить кучу оберточных методов для работы с ними - изощренный мазохизм, из которого проистекает в частности "вложенность 2 порядка". В Lua есть механизм доступа к элементам таблиц на любой глубине через точку, почему бы не использовать готовое и отлаженное? Будешь тогда писать что-то типа: Code: local Checkbox = mainForm.wtMainPanel.wtChilds [ 5 ] .wtEntry.wtCheckboxCheckbox.__widget:Show( true ) В общем, что хотел сказать: в нынешнем виде этот скрипт - способ написать посложнее то, что можно написать просто. Отрицательные эффекты перевешивают положительные. Про ООП в Lua - вот библейские основы: http://www.lua.org/pil Конкретно нужны главы 11, 13, 16 и 17, там подробно и с примерами написано, что именно предусмотрено в Lua для объектно-ориентированного скриптования. Остальное по желанию, но вообще если уж пишешь серьезно на Lua, то неплохо бы ознакомиться хотя бы с руководством, написанным создателем Lua (одним из), благо оно небольшое и все по делу. Побаловаться с чистым Lua можно, подключив к Notepad++ lua.exe нужной версии в стандартную плагу NppExec (идет в комплекте с Notepad++).
  13. А ты возьми список всех объектов в округе, где их погуще, и залоггируй их координаты. Для некоторых все же работает. Но не для всех, что обыдна.
  14. Не GetText() надо, а common.GetAddonRelatedText(). GetText'а не существует. В Texts.(UIRelatedTexts).xdb поле "name" - любая строка, не обязательно имя файла. По этой строке и добываешь этот текст.
  15. Если ты про таблицы, то вот простой тест, выполняется lua.exe v.5.0.3: Code: function getsize( t ) local c = 0 for k, v in pairs( t ) do c = c + 1 end return c end print( "size", getsize{} ) --> size 0
  16. Code: <header color="0xFFCC1111" alignx="center" shadow="1"><rs class="class"> <r name="key"/><r name="value"/></rs></header> Скажи, а там где ты добыл этот текст, еще такие есть? И если есть, тогда расскажи уж, как и где добыл. Это ключевая информация для правильной работы с текстами, в выданной документации об этом только пол-намека. Upd. А, в примерах кое-что есть, хотя и не такое.
  17. Видать, не все удалил. =) Итератор, сгенеренный pairs сразу возвращает nil, если таблица пустая. Цикл не проходит ни одной петли. В 5.0.x нету table.maxn и прочего, что ты написал. Есть только table.getn. Но все это все равно толком работает только для списков. Разрабы юзают Lua как есть, сырьем, библиотеки только стандартные отпилили и влепили Global(), выдранный в ноль из учебника =), и все.
  18. Если бы разрабы нигде не использовали SimpleTexture, то как минимум стрелка на компасе не вращалась бы. И кстати, это не текстура, это контейнер для текстуры. Описатели текстур - UISingleTexture и UITextureElement.
  19. Тут тест может не работать по куче причин. В mods.txt выводятся только результаты вызова LogInfo; если ты вдруг в функцию передашь некоррекный аргумент или еще где ошибешься, то об этом даже не узнаешь, просто ничего не будет работать.
  20. Приятно встретить понимание. Но с точки зрения отладки ждать скорее можно более развернутой диагностики, типа спама в mods.txt всяких ошибок, но не ToWString, как бы он ни был приятен в использовании. Аддоны были и останутся в компетенции именно разработчика, API-то общий. С ближайшим патчем посмотрим на тенденции.
  21. common.LogInfo может выводить и string'и и WString'и. Только зачем в RelatedTexts заводить test1.txt, чтоб просто вывести его в лог? WString'и нужны для текстов в самих аддонах.
  22. Здрасте. Почитал я тут... Мда. Скажу. Разрабы всячески будут не давать доступ в родные аддоны, это очевидно, и надеяться на обратное глупо. Ибо существует ряд спецом защищенных функций, доступных только самим разрабам; debugCommon там, всякие последние protected и пр. А защищены они с целью воспрепятствовать написанию коммерчески вредных для разрабов ботов и автоматизации. И если дать доступ к родным аддонам, это автоматически означает дать доступ к этим защищенным функциям. Так что дальше можно ожидать только дальнейшего отпиливания и ограничения доступа к оригинальным аддонам и функционалу. Мододелам ( ну то есть, Нам, господа =) в конечном счете останется работать только в направлении пассивных аддонов-индикаторов всякого пошиба. Вообще конечно, разрабы с API обосрались. Пока въедешь, как оно устроено (а поэкспериментировать толком не получается - свихнешься ждать, да и никакого фидбека от клиента); документация по API, похоже, выдрана с мясом с какого-то внутреннего ресурса, часть написанного тупо оставляет в недоумении, о чем тут вообще; даже простенький аддон с нуля без всякой диагностики без шансов сделать, не говоря уж об отладке. С XML'никами этими, которые *.xdb, геморрой получается тот еще - их с текстурами выходит целая орда (кто-нить трогал экспортер? =), так они еще друг на друга всячески плотно ссылаются; без редактора, или хотя бы быстрого вьювера, про cерьезные аддоны, типа красивой и умной сумки, например, можно смело забыть. Но и у нас тут хорошо: упорные позывы по всему форуму генерить тексты в скриптах с помощью всяких ToWString выглядят диковато. В какой кодировке ваши скрипты? А разрабам это дело локализовывать, в том числе и в Азию, что без UTF нереально. На хардкод-текстах из скриптов можно в локализации таких геморроев огрести, мало не покажется никому. В большой конторе проще жестко запретить. А WString'и можно заводить как файлики в USC-2 Little Endian, в ZoneAnnouncer'е это вполне ясно показано. Их потом собирают в кучку и переводят. Если кому-то надо их менять из скрипта, обратите свое внимание на такие структуры как SampleDefault.(UIRelatedTextures).xdb и SampleDefaultExt.(UIRelatedTextures).xdb из пакета документации, а также на методы группы common.GetAddonRelated*() в самих доках. Вроде бы это оно, во всяком случае очень похоже. Хотя, безусловно, гемора с текстами добавляет неслабо. В чат никто за просто так спамить скриптовым генератором не даст, это тоже, в общем, понятно. А вот combatlog и chatlog можно писать сколько угодно и наворачивать до безобразия. Чот, блин, разогнался, накатал целую простыню... =)
×
×
  • Создать...

Важная информация

Пользуясь сайтом, вы принимаете Условия использования