Поскольку я довольно широко использую DYNEVAL и DYNAMIC (в том числе и в своём фреймворке), возникла следующая мысль: было бы очень неплохо иметь возможность работать с кодом самих локаций, т.е. получать, изменять и сохранять его программным образом.
Например:
LOCGETCODE(<ИмяЛокации>) — получить код локации
LOCSETCODE, <ИмяЛокации>, <ПрограммныйКод> — установить код локации
Спору нет, широкого применения этот функционал не получит, поэтому попробую пояснить для чего это нужно мне лично:
В своём фреймворке во многих командах автор должен передать программный код, который должен выполняться в тех или иных случаях (например, что должно происходить при перемещении предмета). Нюанс в том, что сейчас предпочтительней передавать этот код как строку ("…" или {…}), потому что тогда фреймворк автоматически заменяет в нём ссылки на объекты на их фактические значения. Например при работе с экземплярами объектов это просто необходимо — автор в коде указывает просто $ОБЪЕКТ, а при выполнении $ОБЪЕКТ заменяется на фактический экземпляр объекта, что позволяет точно знать, с каким именно объектом в каком месте нужно производить манипуляции. Если бы можно было программно работать с кодом локации, то автор мог просто указывать имя локации, которая должна вызываться (для многих это было бы привычней, да и сообщения об ошибках были бы более информативнее).
Неактивен
Nex написал:
Переделывать нужно не QSP, а плохо написанный фреймворк.
Да, эту проблему можно решить и по-другому — с существующим функционалом платформы (что уже сделано), но для авторов (меня в том числе) это будет гораздо менее удобно и кода писать в игре нужно будет гораздо больше.
Неактивен
Nex написал:
Переделывать нужно не QSP, а плохо написанный фреймворк.
Мало понимаю в тонкостях программирования, и все же более продуктивным мне кажется не оценочная критика продукта, а разъяснение в чем именно его можно улучшить.
Отредактировано Korwin (05.08.2011 12:57)
Неактивен
Насколько я понял, претензия Олегуса заключается в том, что в его фреймворке ему приходится каждый раз передавать строку кода в "явном виде", вместо того, чтобы один раз задать ее где-то и после только ссылаться.
Для решения этой проблемы он предлагает переделать QSP, т.к. считает, что по-другому эту проблему не решить.
Я считаю, что эту проблему можно решить существующими средствами. То есть,
один раз задать код где-то и после только ссылаться
можно и сейчас, просто Олегус не знает, как это сделать.
Возможно, я ошибся насчет сути претензий: без бутылки водки и подробных разъяснений автора в этих адских дебрях хрен разберешься. В таком случае прошу меня поправить.
Неактивен
Nex написал:
Насколько я понял, претензия Олегуса заключается в том, что в его фреймворке ему приходится каждый раз передавать строку кода в "явном виде", вместо того, чтобы один раз задать ее где-то и после только ссылаться.
Для решения этой проблемы он предлагает переделать QSP, т.к. считает, что по-другому эту проблему не решить.
Я считаю, что эту проблему можно решить существующими средствами. То есть, один раз задать код где-то и после только ссылаться можно и сейчас, просто Олегус не знает, как это сделать.
Возможно, я ошибся насчет сути претензий: без бутылки водки и подробных разъяснений автора в этих адских дебрях хрен разберешься. В таком случае прошу меня поправить.
Ты как всегда ничего не понял, а твои измышления насчёт "каждый раз", "решить существующими средствами" говорят о том, что ты не особо утруждался (чтобы понять).
Программный код задаётся автором один раз — когда он прописывает то или иное действие. В дальнейшем фреймворк вызывает именно этот сохранённый код. Однако в некоторых случаях автору в этом коде нужно ссылаться на некие изменяемые значения, например на идентификатор конкретного экземпляра обрабатываемого этим кодом предмета.
С одной стороны это можно сделать через передачу в код параметров, вызывая DYNEVAL или DYNAMIC с указанием параметров, которые попадают в массив ARGS. Но при этом автору каждый раз нужно будет восстанавливать эти значения из параметров, что не особо удобно.
Возьмём код из примера:
GS 'УстановитьДействие', 'Сигарета', 'Взять сигарету', $ico['взять'], { Result=IIF(func('Местонахождение', ИГРОК, $ОБЪЕКТ, ИГРОК), Пропускать, Использовать) }, '', { if func('Переместить', ИГРОК, $ОБЪЕКТ, 0, ИГРОК) = Продолжить: GS 'ТекстНаЭкран', 'п. Вы взяли ((сигарету|$ОБЪЕКТ)).' end }
Код задаётся автором один раз и вызывается фреймворком при формировании меню объекта. Смысл этого модуля — добавить в меню пункт, который будет появляться только если текущий экземпляр сигареты отсутствует у игрока, и который перемещает экземпляр объекта из того места, где он сейчас находится, в инвентарь игрока. То есть в момент вызова данных кусков кода фреймворк заменяет переменную $ОБЪЕКТ на пакет данных, который содержит идентификаторы объекта и места, где конкретный экземпляр объекта находится.
Разумеется (ещё раз повторю) это можно переделать под передачу параметров (и именно так сделано для вызова не участков кода, а локаций):
GS 'УстановитьДействие', 'Сигарета', 'Взять сигарету', $ico['взять'], { Result=IIF(func('Местонахождение', ИГРОК, ARGS[0], ИГРОК), Пропускать, Использовать) }, '', { if func('Переместить', ИГРОК, ARGS[0], 0, ИГРОК) = Продолжить: GS 'ТекстНаЭкран', 'п. Вы взяли ((сигарету|<<ARGS[0]>>)).' end }
Но в случае больших модулей это просто неудобно.
Кстати, фреймворк иногда дописывает код, чтобы обойти баг/фичу QSP с глобальной видимостью переменной Result на все вызываемые через GS локации.
Да, и я не предъявляю кому-либо "претензий" из-за того, что "по-другому эту проблему не решить". Пока что все задачи, которые я перед собой ставлю, я решаю существующими средствами. Просто это требует куда большей рутины — только и всего. Поэтому и тема эта в разделе "Предложения"…
Неактивен
Ты как всегда ничего не понял
Толсто.
- Доктор, почему когда я делаю вот так, мне больно?
- А вы не делайте так.
Страдания от попыток реализовать объектную систему на движке, для этого не предназначенном, вполне закономерны.
Хочешь "просто и удобно" - используй заточенный на объекты и программизмы движок, например INSTEAD.
Берешься забивать гвозди микроскопом - не жалуйся.
Неактивен
Nex написал:
- Доктор, почему когда я делаю вот так, мне больно?
- А вы не делайте так.Страдания от попыток реализовать объектную систему на движке, для этого не предназначенном, вполне закономерны.
Хочешь "просто и удобно" - используй заточенный на объекты и программизмы движок, например INSTEAD.
Берешься забивать гвозди микроскопом - не жалуйся.
Т.е. работу с объектами ты сравниваешь с гвоздями, а QSP в этом контексте с микроскопом? Всё же не совсем подходящая метафора.
Впрочем, твой обычный лозунг — если не нравится, как всё есть, используй другую платформу! — я услышал. Развивать дискуссию в этом направлении с тобой, как обычно, смысла нет.
Неактивен
работу с объектами ты сравниваешь с гвоздями, а QSP в этом контексте с микроскопом? Всё же не совсем подходящая метафора.
QSP настолько же предназначен для работы с объектами, насколько микроскоп - для забивания гвоздей. То, что в QSP можно при известном усилии делать объекты, ничего не меняет - ведь и микроскопом можно гвозди забить.
твой обычный лозунг — если не нравится, как всё есть, используй другую платформу!
Врешь, это никогда не было и не будет моим лозунгом.
Теперь по сути вопроса:
Программный код задаётся автором один раз — когда он прописывает то или иное действие. В дальнейшем фреймворк вызывает именно этот сохранённый код. Однако в некоторых случаях автору в этом коде нужно ссылаться на некие изменяемые значения, например на идентификатор конкретного экземпляра обрабатываемого этим кодом предмета.
Вот я "сослался на некое изменяемое значение":
$ОБЪЕКТ = 'ПЕРВОЕ ЗНАЧЕНИЕ' $code = {*PL $ОБЪЕКТ} $ОБЪЕКТ = 'ВТОРОЕ ЗНАЧЕНИЕ' DYNAMIC $code
Все работает без всяких ARGS.
Неактивен
Nex написал:
Теперь по сути вопроса:
Программный код задаётся автором один раз — когда он прописывает то или иное действие. В дальнейшем фреймворк вызывает именно этот сохранённый код. Однако в некоторых случаях автору в этом коде нужно ссылаться на некие изменяемые значения, например на идентификатор конкретного экземпляра обрабатываемого этим кодом предмета.
Вот я "сослался на некое изменяемое значение":
Код:
$ОБЪЕКТ = 'ПЕРВОЕ ЗНАЧЕНИЕ' $code = {*PL $ОБЪЕКТ} $ОБЪЕКТ = 'ВТОРОЕ ЗНАЧЕНИЕ' DYNAMIC $codeВсе работает без всяких ARGS.
Забавно, что ты допускаешь возможность, что я о таком способе не знаю. Увы, но в приведённом тобой примере решение строится на использовании глобальных переменных. В моём случае они неприменимы — если в коде будут присутствовать несколько функций, работающих с этим и другими объектами (которые могут в свою очередь вызывать другие функции), то значение глобальной переменной, в которой автор рассчитывает хранить идентификатор используемого в той или иной функции объекта, будет неконтролируемо меняться. Полагаю, примерно из-за подобных же проблем и придумали аргументы у функций.
Но да, в простейших случаях (типа такого, как ты показал) приведённое тобой решение работает. Но (как и в случае с Роджером) для решаемых мной задач это пробовалось и не подходит.
Неактивен
Покажи конкретный пример, где это "не подходит".
Вне фреймворка, просто пример кода. Я пытаюсь понять, что тебе нужно, но пока упираюсь в то, что без тотального перелопачивания адского движка яснее не станет.
$ОБЪЕКТ - не глобальная переменная? А что?
"Фактический экземпляр объекта"? - что это означает?!
"Пакет данных, который содержит идентификаторы объекта и места, где конкретный экземпляр объекта находится"? - аналогично.
Приведи пример кода, без фреймворка?
Неактивен
Nex написал:
Покажи конкретный пример, где это "не подходит".
Вне фреймворка, просто пример кода. Я пытаюсь понять, что тебе нужно, но пока упираюсь в то, что без тотального перелопачивания адского движка яснее не станет.
$ОБЪЕКТ - не глобальная переменная? А что?
"Фактический экземпляр объекта"? - что это означает?!
"Пакет данных, который содержит идентификаторы объекта и места, где конкретный экземпляр объекта находится"? - аналогично.
Приведи пример кода, без фреймворка?
Во время экспериментов со свойствами объектов и их обработчиками я отрабатывал в том числе такой пример:
Нужно получить светимость лампы в зависимости от того, что в ней налито.
У меня были объекты "Лампа", "Масло", "Керосин" и "БожьяСлеза". У каждого из них было свойство "Светимость": у лампы — 0, у масла — 30, у керосина — 60, а у божьих слёз — все 100.
И у лампы был обработчик события "Получение свойства Светимость у Лампы" с модулем (как раз прописываемым автором), который при получении светимости лампы смотрел, что в лампе содержится, и прибавлял значение светимости содержимого к значению светимости лампы.
В результате в модуле описания локации автору достаточно просто проверить свойство "Светимость" лампы на те или иные значения — он сразу же получал готовое значение светимости с учётом того, что в неё налито.
В данном случае как раз и происходит вызов различных участков кода, ранее сохранённых автором (модуль формирования описания локации, модуль обработки свойства и т.п.), в которых используются идентификаторы разных объектов. Если использовать для этого глобальные переменные, то на каком-то уровне их значение просто подменится.
Пример кода, выполняющего эти функции без фреймворка, мне писать что-то не хочется — слишком много рутины и вспомогательного кода, а фреймворк для того и писался, чтобы этого избежать.
Неактивен
...вызов различных участков кода, ранее сохранённых автором (модуль формирования описания локации, модуль обработки свойства и т.п.), в которых используются идентификаторы разных объектов.
А берутся-то откуда эти идентификаторы? И как выглядит значение идентификатора?
Отредактировано Nex (07.08.2011 07:58)
Неактивен
Nex написал:
...вызов различных участков кода, ранее сохранённых автором (модуль формирования описания локации, модуль обработки свойства и т.п.), в которых используются идентификаторы разных объектов.
А берутся-то откуда эти идентификаторы? И как выглядит значение идентификатора?
Изначально, строковое значение идентификатора объекта задаётся автором, числовое — присваивается фреймворком. Идентификатор экземпляра объекта, как правило, создаётся автоматически при нажатии на ссылку на экране и представляет собой числовое значение, по которому можно определить ID самого объекта и ID контейнера, в котором он находится.
В модуль идентификаторы попадают по-разному: либо через параметр, либо в тексте модуля все вхождения подстроки "$ОБЪЕКТ" заменяются на его числовое значение.
Неактивен
в тексте модуля все вхождения подстроки "$ОБЪЕКТ" заменяются на его числовое значение.
В таком случае, что здесь может "поменяться впоследствии при вызове других функций", если числовое значение уже на момент вызова кода подставлено вместо $ОБЪЕКТ?
Отредактировано Nex (07.08.2011 12:14)
Неактивен
Nex написал:
в тексте модуля все вхождения подстроки "$ОБЪЕКТ" заменяются на его числовое значение.
В таком случае, что здесь может "поменяться впоследствии при вызове других функций", если числовое значение уже на момент вызова кода подставлено вместо $ОБЪЕКТ?
Если числовое значение подставлено в сам код, то ничего не поменяется. Но, Некс, именно это я и сделал. И чтобы такой подход можно было перенести на локации, а не только на строковый код, мне бы и хотелось иметь в арсенале те функции, с описания которых я и начал тему.
Ты же (помнишь?) предлагал вместо этого задействовать глобальные переменные. Вот они как раз и будут меняться.
Неактивен