Blitzmax
Четверг, 02.05.2024, 19:19
Приветствую Вас Гость | RSS
 
Главная СтатьиРегистрацияВход
Меню сайта
Категории каталога
Разное [2]
BlitzMax [5]
Доки/Уроки [8]
Игровое программирование [1]
Наш опрос
Оцените скорость работы с сайтом
Всего ответов: 112
Главная » Статьи » Доки/Уроки

Советы и секреты
  1. Аналог оператора With
    В разных языках есть оператор With, смысл которого в том, что к полям объекта подставленному к оператору, производится быстрый доступ и в тексте и в скомпилированном коде (за счет занесения объекта в регистр процессора). Данного оператора в Blitzmax нету. Но его можно частично заменить с помощью новой локальной переменной. Поскольку объявлять переменную можно в любом месте, и новая переменная, скорее всего (не гарантированно), помещается в регистр, то объявив локально и коротким именем переменную с нужным нам объектом, в большинстве случаев, можно добиться аналогичного результатата. Это можно назвать решением недостатка языка 1.7.
    Пример:
    Method Abc( argument1:TMyType, argument2%, ... )
    ...
    Local a:TMyType = argument1
    a.Field1 = New Type2
    a.Method1( ... )
    ...
    End Method
  2. Использование GCCollect
    Не рекомендую использовать GCCollect в главном цикле - это снижает производительность. Автоматическая уборка мусора вполне справляется с большинством задач. Лучше использовать эту команду в случаях, когда было резервирование очень больших объемов памяти и память лучше освободить, чтобы поскорее уменьшить нагрузку на ресурсы системы.
    Режимы сборщика задаются GCSetMode:
    [1] - автоматический
    [2] - ручной
    [-1] - агрессивный (недокументирован)
  3. Инициализация новых переменных и объектов
    Blitzmax автоматически инициализирует новые переменные, поэтому отпадает необходимость инициализировать пустые переменные объектов значением NULL. Можно писать просто:
    Local obj:TMyType;
    Вместо:
    Local obj:TMyType = NULL;
    То же относится и к полям типов/классов. Также все значения нового массива будут проинициализированы нулями.
  4. Определение состояния списка
    Чтобы определить, пуст список или нет, не надо использовать TList.Count() - это медленый метод, надо использовать TList.IsEmpty().
  5. Проход по многомерному массиву
    Если мы объявили многомерный массив как массив значений (Local a[n,m]), а не массив массива (a[n][m]), то пройти весь массив можно не стандартным способом с вложенными циклами, а одним foreach:
    Local a[2,2]
    a[0,0]=1; a[0,1]=2; a[1,0]=3; a[1,1]=4
    For Local i:Int = EachIn a; Print i; Next;
    Из примера видно, что проход выполняется сначала по последним индексам.
    Но, как всегда, есть и неприятный момент: если вы заметили я инициализировал каждый элемент массива отдельно. И сделал это потому, что при подобном объявлении Blitzmax не поддерживает инициализацию массива. И красивой записи, как для массива массивов: Local b[][] = [[1,2],[3,4]] сделать не даст.
  6. Запись в строку по индексам : string[2]=78
    Нормального доступа к элементам строки в Blitzmax'e нет. Марк типо сильно боится дураков-программистов и сильно о них заботится. Он, наверное, пропитался духом псевдо-любви к умалишенным в ущерб неумалишенных. Объяснение, почему он не делает нормальный индексный доступ к строкам, а только чтение, меня просто развеселило: он заботится о том, что, если мы передаем строку в функцию, ее там кто-то может изменить. А типа чтобы ее не изменили стопроцентно надо ее копировать, а не передавать через ссылку. А это целых 7 лишних символов каждый раз набирать: ".Copy()". Вопрос а нафик нам вообще надо сохранять строку? Или мы настолько тупы, что не знаем, что пишем? И нам ни за что не известно будет ли функция менять строку или нет? Ппц просто. Я уже молчу про то, что это решается на уровне языка элементарно, и не в одном языке делалось: аргумент функции объявляется как ссылка или как значение. Если ссылка - передаем ссылку на строку и она может быть изменена после работы функции. Если значение - то строка копируется и что там функция будет с ней делать, нас не волнует: у нас оригинал, а там - копия. Все давно известно, ничего не надо изобретать и писать лишних 7 символов тоже не надо. Но зато придется изобретать нам. Итак, решение:
    Local str$ = "Hello"
    Print str

    Local p:IntPtr = IntPtr(Varptr(str))
    Local
    pchar:ShortPtr = ShortPtr(p[0])
    pchar :+ 6
    'this offset depends on the String structure

    pchar[0]=Asc("H")
    pchar[1]=
    Asc("e")
    pchar[2]=
    Asc(" ")
    pchar[3]=
    Asc("h")
    pchar[4]=
    Asc("e")

    Print str
    Или вот так одной строкой:
    Local pchar:Short Ptr = Short Ptr(Int Ptr(Varptr(str))[0]) + 6
  7. Переопределение полей в наследниках
    В наследнике можно переопределить поле предка с тем-же названием. Поле предка будет доступно под тем-же именем с помощью оператора Super.
    Как это можно использовать: можно сделать поле со счетчиком в каждом наследнике отдельно и подсчитывать, таким образом, количество экземпляров каждого класса в отдельности.
    Ньюанс: первичное поле остается в предке, к нему можно получить доступ по дереву предков с помощью Super. И это может повлечь за собой повышенные расходы к памяти, если поле требует ее много. Кроме того, считаю это небезопасным способом для разработки, т.к. не выдается никаких сообщений при компиляции по поводу переопределения полей. И можно при последующей доработке класса, нечаянно переопределить какое-либо существующее поле, что приведет к ошибкам в работе логики программы.
  8. Рисуем кусок изображения
    Используем SetViewport
    Function DrawImageRect(img:TImage, x#, y#, rx#, ry#, rw#, rh#)
        SetViewport x, y, rw, rh
        DrawImage img, x - rx, x - ry
        SetViewport(0, 0, GFX_WIDTH, GFX_HEIGHT)
    End Function
    Особенности: надо знать абсолютные координаты.
    Недостатки: SetViewport не всеми картами поддерживается.
  9. Вызов глобальной функции при конфликте имен с методами класса осуществляется, если поставить перед именем функции точку. Например:
    .SetAlpha( _alpha )
    Вызовет глобальную функцию, даже если у описываемого класса есть метод SetAlpha.
  10. Уменьшение утечек памяти при загрузке ресурсов.
    Подобные проблемы периодически возникают и фиксятся от версии к версии с различными форматами картинок (png, jpg). Надежнее самому этого избегать, чем надеятся что текущая версия будет без глюков или ждать фикса.
    Принцип прост: надо загрузить ресурс один раз. Тогда утечка будет только один раз, а не постоянно при загрузке ресурса. Потом используем загруженный ресурс по мере надобности.
    Это можно реализовать с помощью менеджера ресурсов или проще, заведя глобальные переменные и загружая ресурсы в них (тот-же менеджер ресурсов, но сильно упрощенный).
  11. Комментирование многострочных выражений
    Перед комментарием ставим команду продолжения строки, примеры:
    'пример с потоковым стилем
    local tw:Tween = gtw.pk()..
      ..'.i( t.MoveBy( -8, 0, .502 ) )..
      .i( t.seq_()..
        ._( t.AlphaFromTo( 0, .52, .205) )..
    '...
    'пример с данными
    local data:String[] = [..
        "one",..
        ..
    '"first",..
        "two"..
    ]

    Это может пригодиться, если мы задаем аргументы функции в несколько строк, или пишем используя потоковый стиль (1я часть примера) или в наборах данных (2я часть примера).
    И еще хинт: кирилицей (и прочим юникодом) можно делать комментарии без специальных обозначений - эти символы игнорируются (но для подсветки лучше их как-то обозначать).


Категория: Доки/Уроки | Добавил: oxid (16.07.2007)
Просмотров: 5274 | Рейтинг: 4.0/1 |

Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Форма входа
Поиск
Ссылки
Статистика
Copyright Oxid © 2024
Сайт создан в системе uCoz