Pull to refresh
7
0
Александр @yizraor

Программист

Send message
ой, ну да, вторая задача по-любому только на современных версиях дельфей работать будет, там же генерик используется ))
что-то сразу и не обратил внимания на генерик )
кхм, я не спец по дельфям, но набросал у себя в блокноте следующее (пусть будет и здесь, чтобы потом сравнить с правильными ответами):

Задача 1:
не знаю, но подозреваю:
уж не будет ли выполнен OutData.Release() в функции AddData() до вызова функции CreateMerged_IData() ???
(что-то мне звучит бредово, но других мыслей нет, да и когда в дельфях не было досадных багов и/или недоработок? по-хорошему, надо в дизассемблере это предположение проверять)

Задача 2:
После выполнения obj.Free() переменная obj сохраняет значение (obj <> nil), и в старых дельфях код должен работать как часы…
Но как быть с современными версиями дельфей, которые умеют «автоматический подсчет ссылок» ???
( инструкция «obj := nil» по сути есть «пинок» нынешним дельфям для выполнения «obj.Release()», но память obj^ к этому моменту может быть уже невалидной! разве нет? )

P.S.:
отчаянно не хватает информации о версии Delphi, на которой код работает неправильно ))
идея хороша, мне нравится.
возможно, и правда, что лет через несколько такие элементы управления будут часто использоваться в сенсорных интерфейсах.
и наверняка в более проработанном виде.

меня вот смущает тот факт, что пока эту кнопку не нажмешь — не поймёшь, что её можно перетаскивать…
тот факт, что кнопка отрисована объёмно, с тенью, навроде фишки, лежащей на столе («стол» = остальной плоский интерфейс), это видимо у Вас «подсказка» пользователю — что функционал кнопки шире, чем просто нажатие?
по-моему, этого недостаточно — добавить бы в иконку вокруг лупы четыре маленькие стрелочки в разные стороны, и мне кажется, даже такие тугие юзеры, как я, будут быстро привыкать к таскаемости кнопки поиска, т.к. подсказка (в виде этих стрелочек) будет видна уже ДО нажатия кнопки.
( возможно, именно поэтому — что недостаточно бросается в глаза особенный «характер» кнопки поиска, Вас и не упомянули в результатах, типа сочли недоделанной по дизайну основную Вашу идею… но это только моё предположение… не спросишь у самих членов жюри — не узнаешь наверняка ))
да ладно Вам, в инете есть статей с «переводом» этих терминов, и вполне возможно что есть энное количество людей, привыкших к «переводам» больше, чем к оригинальным англоязычным версиям… не все же начинают с чтения англоязычного DirectX SDK.
да и автор заботливо расставил в скобках узнаваемые аббревиатуры RTV, DSV, UAV, SRV и т.д., так что проблема чтения не так уж велика… я так и вовсе не заметил проблемы, т.к. капсовые аббревиатуры пролетали в мозг быстрее предшествующего им «перевода» ))
спасибо ) тоже весьма познавательно.
кстати, возвращаясь к Half-Life — для меня там 90% «атмосферы» делают звуки… вроде каждый звук сам по себе неестественный (если достать и воспроизвести проигрывателем), но в игровом процессе все вместе они делают почти всю атмосферу игры…
наверно, там тоже какая-то «магия» покопалась?..
нет ли у Вас, случаем, инфы на тему хитростей озвучки? :))
Спасибо за статью, легкая и интересная… прочитал на одном дыхании.
Никогда особо не задумывался, что меня цепляет в некоторых играх (ну разве что про Half-Life (первый), Горький-18, Doom 3 могу сказать, что это их атмосфера — она бесподобно проработана).
Теперь стало яснее — есть и психологические моменты, которые, будучи правильно примененными, сильно повышают интерес к игровому процессу… действительно, X-COM: Enemy Unknown для меня был бы без базы совсем не тот, и скорей всего показался бы унылой цепочкой однообразных миссий. А вот TIS-100, о котором недавно даже упоминали на хабре, наоборот, зацепить что-то не смог — вроде интересно решать каждое задание само по себе, но «база» никак не «развивается», кроме открытия новых задачек — вот бы ещё что-то там прогрессировало (наверно, это называется — «я зажрался» :)
ага, когда до 7:50 досмотрел, тогда и понял что уровни тоже переделаны ))
а до того, казалось, что вроде как всё то же самое, планировка уровней совпадает же… видимо не вглядывался
Спасибо автору за публикацию! (жаль плюсануть не могу, кармы не хватает)
И технически любопытно, и поностальгировал немного по ушедшему детству, глядя видео… Музычка прям-таки навевает ))
Весь первый уровень недоумевал, что не так с музыкой — вроде и классная, но как-будто должна быть другая. Потом понял — в этом и хак, что с другой игры музыку взяли… если не ошибаюсь — из «Ninja Cat»?
Blackmorsha, спасибо за приподнятое настроение, Ваш сарказм очарователен ))

только вот просьба не принимать близко к сердцу наши ответы.
никто не спорит, что указанный Вами метод имеет право на жизнь, просто он имеет не меньше проблем, чем другие способы.

давайте на этом прекратим дискуссию насчет Вашего способа в организации цикла отрисовки. кому тема интересна, тот в любом случае прочитает комментарии и примет Вашу инфу к сведению… кому не нужно — тот и основной текст не осилит.

добавлять Ваш способ в текст публикации, извините, не буду — для Windows он не более удачен, чем OnPaint+InvalidateRect, по другим платформам — не знаю.
другое дело, если появится инфа о способах, не связанных с событием OnIdle(), но не менее корректных в плане обработки поступающей очереди сообщений — такое буду добавлять, если где чего узнаю.

P.S.:
с FireMonkey, признаться, не связывался. попробую, как-нибудь попозже покопать его.
а под Android только на Java программировал, и то немного… Жду продолжений Вашей публикации :)
мда, с PostQuitMessage() и PostMessage(WM_CLOSE) я немного ошибся, они тоже поломаны.
хотя и будут работать, если в цикл добавить строку с проверкой Application.Terminated:
 repeat // main loop
  Application.ProcessMessages;
  if CheckBox1.Checked then ObjMove;
  DoRender;
  Label1.Caption:=format('NF %d ',[NFrame]);
  inc(NFrame);

  // добавленная строка
  BClose := ( BClose ) or ( Application.Terminated );
 until BClose;


к сожалению, не смог отредактировать свой предыдущий комментарий
Спасибо за комментарии.

Я загрузил Ваши исходники и посмотрел в Delphi XE7.
Работает неплохо, но это не более удачный подход, чем раздел «OnPaint + InvalidateRect» из текста публикации.

У меня в Вашем примере работают корректно, вопреки некоторым из утверждений MrShoor:
— хинты
— PostQuitMessage()
— PostMessage(Form1.Handle, WM_CLOSE...)
— PostMessage(Form1.Handle, WM_QUIT...)
— синхронизация через TThread.Synchronize (не уверен, но по крайней мере мне не удалось создать проблемный вызов этой функции)

Сломаны следующие моменты:
— Application.OnIdle
— Application.Terminate() (правда, это легко исправляется, буквально одной строчкой кода)
— ресайз формы (если в системе включена опция «Отображать содержимое окна при перетаскивании», то изменение размеров у обычных окон выполняется плавно по мере движения мыши и со мгновенной перерисовкой; Ваш же пример не хочет перерисовывать окно до тех пор, пока пользователь не отпустит правую кнопку мыши)

В целом Ваш подход с Application.ProcessMessages() нетипичен для программирования под многозадачные ОС, типа Windows/Linux, и др…
Что ни говори, а корректная обработка очереди сообщений всё-таки нарушается (Application.ProcessMessages — это тот инструмент, который надо использовать с осторожностью, да и бесконечные циклы принято организовывать другими способами). А мне при подготовке публикации хотелось оставаться в рамках концепций программирования под платформу Win32, поэтому в тексте публикации использованы лишь те способы, которые там сейчас есть.

Признавайтесь: в своё время Вы много программировали под MS-DOS? :)
Спасибо за комментарий!

Первый вариант (OnPaint + InvalidateRect) я тоже считаю неверным.
Но я не мог о нём не упомянуть, поскольку он является самым тривиальным…
Может быть, я недостаточно акцентировал внимание на неудачности этого способа?

А правильно делать так:
Рисовать сцену только в OnPaint, а в OnIdle делать только InvalidateRect.

В общем-то вариант с использованием OnIdle() у меня работает именно так :)

Тогда вы решите проблему со свернутыми окнами, заблокированными экраном по Win+L, да и вообще во всех потенциально возможных случаях + исчезнет проблема с мелькающей дефолтной отрисовкой на обработку WM_PAINT.

А Вы пробовали в программе-примере закомментировать то, что «пришлось городить» и запустить под отладчиком?
Я, когда запускаю под отладчиком, сворачиваю окно программы и ставлю брейкпоинт в обработчике OnPaint() — то он, этот обработчик не вызывается, но программа всё равно «кушает» процессор.
Почему? Потому что цикл OnIdle() продолжает работать безо всяких пауз и остановок.

То условие, которое Вы процитировали, отвечает в моём коде за (временное) прекращение обработки цикла OnIdle():
procedure TFormMain.OnApplicationIdle(Sender: TObject; var Done: Boolean);

Если параметр Done после исполнения обработчика события будет равено TRUE, то выполнение программы будет приостановлено до тех пор, пока не появятся новые оконные сообщения, а если FALSE — то в случае отсутствия новых оконных сообщений будет повторное срабатывание события OnIdle().

Не могу понять, кто из нас с Вами в этом вопросе кого недопонял — то ли я неправильно прочитал Ваш комментарий, то ли Вы недостаточно внимательно просмотрели текст публикации и исходники примера…

P.S.:
по поводу заблокированного экрана — спасибо за мысль, сам я не догадался это проверить — но попробую сегодня вечером

Information

Rating
Does not participate
Location
Москва и Московская обл., Россия
Date of birth
Registered
Activity

Specialization

Software Developer, 1C Developer
Lead
SQL
Delphi
C#
WPF
Algorithms and data structures
Code Optimization
Asynchronous programming
Multiple thread