15.07.2009 14:08 |
Lester |
давно не отписывался( но работа идет и быстрыми темпами ), сейчас закончил новую фишку - парсер для текста на разных языках программирования, работает все просто:
Lexer lexer( LEX_CPP );
lexer.Parse( text );
String html = lexer.AsHTML();
парсеру можно отдать свой список ключевых слов, переменных, типов и т.д., от парсера также можно получить список стилей( массив размером с исходную строку с индексами стилей ), в TODO - экспорт в RTF, PDF etc., простая привязка к GUI.
Вот пример использования:
Вложение 110743
тут не все видно, но строки, числа и т.п. тоже подсвечиваются как надо
|
03.05.2009 14:24 |
Lester |
Цитата:
Сообщение от Marchello
Вот например метод FromArray, ты там юзаешь memcpy для того чтобы заполнить масив в this извне.
Но ведь при таком раскладе не будут вызываться операторы '=' для
кастумных типов. Хотя может тут какой-то скрытый смысл?
|
нет - просто сделал под себя, С-ые массивы не нуждаются в операторе копирования( т.к. в C нет классов ), а в С++ я использую vector, согласен - я предопределю этот метод для базовых типов, а для остальных сделаю через явное копирование
Цитата:
Сообщение от Marchello
И потом, скольо весит пустой такой массив? У меня в 2008 студии пустой вектор весит 20 байт (и 24 в релизе), тогда у тебя выйдет где-то:
(20+20+20) + 6*4 (bool, size_t, ArraySortFunction) + 2*sizeof(T) +
+ размер String (который будет минимум 4*2 байт) = 100 байт для типа int.
|
обычно содержимое массива значительно больше 100 байт, в данном случае я думаю это оправданная трата ресурсов, но конечно же посмотрю где можно будет соптимизировать, спасибо за совет
Цитата:
Сообщение от Marchello
А потом еще вызывается reserve(256) в конструкторе...
|
он позволит в большинстве случаев обойтись без лишних движений по мере заполнения массива, как по мне затраты на выделение/перемещение блоков памяти для каждого нового элемента стоят большего внимания чем небольшой перерасход памяти
Цитата:
Сообщение от Marchello
Я вот думаю даже иметь две реализации класса массива - первая ну как обычно, и вторая - для типов не имеющих кастумного оператора присваивания (аля POD). Тогда для простых типов можно будет
повсевместно юзать memcpy - что упростит и ускорит это дело
|
как я уже писал - можно просто переопределить этот метод для таких типов, например - void Array<char>::FromArray, благо шаблоны позволяют такое
Цитата:
Сообщение от Marchello
ну и в таком случае конечно не использовать std::vector, будет такой себе PlainArray - конечно с меньшей функциональностью, но зато шустрый (что важно для gamedev-a).
|
лично проведенные бенчмарки( на массивах из пяти миллионов элементов ) показали, что vector ничем не уступает С-массиву по скорости, видно оптимизация все разворачивает в работу с тем же С-массивом
|
03.05.2009 13:50 |
Marchello |
Цитата:
Сообщение от Lester
растет пока проект - много переписал, т.к. понял, что ужасно, в частности самый первый пример - массивы
|
Вот у меня есть пара вопросов (даже не вопросов а мыслей..). Да, массив получился навороченей некуда )) я даже все и не смотрел.
Вот например метод FromArray, ты там юзаешь memcpy для того чтобы заполнить масив в this извне.
Но ведь при таком раскладе не будут вызываться операторы '=' для
кастумных типов. Хотя может тут какой-то скрытый смысл?
И потом, скольо весит пустой такой массив? У меня в 2008 студии пустой вектор весит 20 байт (и 24 в релизе), тогда у тебя выйдет где-то:
(20+20+20) + 6*4 (bool, size_t, ArraySortFunction) + 2*sizeof(T) +
+ размер String (который будет минимум 4*2 байт) = 100 байт для типа int.
А потом еще вызывается reserve(256) в конструкторе...
Короче, такой пустой масив это == int[25]
Хотя память сейчас не критична.
Я вот думаю даже иметь две реализации класса массива - первая ну как обычно, и вторая - для типов не имеющих кастумного оператора присваивания (аля POD). Тогда для простых типов можно будет
повсевместно юзать memcpy - что упростит и ускорит это дело, ну и в таком случае конечно не использовать std::vector, будет такой себе PlainArray - конечно с меньшей функциональностью, но зато шустрый (что важно для gamedev-a).
|
17.04.2009 19:55 |
Lester |
Несколько моих бредовых идей по стилю написания кода гуи( ес-но это альтернативный вариант и пользоваться им необязательно ):
Пример цельного куска кода:
PHP код:
// IDs enum { ID_ITEMS, ID_CHECK_ALL, ID_UNCHECK_ALL };
// Create Dialog dlg = DIALOG( caption ); VLAYOUT LABEL( ID_ANY, "Select one of:" ) HLAYOUT CHK_LISTBOX( ID_ITEMS, choices ) VLAYOUT BMP_BUTTON( ID_CHECK_ALL, plus_xpm ); BMP_BUTTON( ID_UNCHECK_ALL, minus_xpm ); END_LAYOUT END_LAYOUT STD_BUTTONS( ID_OK | ID_CANCEL ); END_LAYOUT
// Pointers CheckListBox* items = (CheckListBox*) dlg->FindByID( ID_ITEMS ); BitmapButton* check = (BitmapButton*) dlg->FindByID( ID_CHECK_ALL ); BitmapButton* uncheck = (BitmapButton*) dlg->FindByID( ID_UNCHECK_ALL );
// Actions check->SetAction( ID_ITEMS, ACTION_CHKLISTBOX_CHECK_ALL ); uncheck->SetAction( ID_ITEMS, ACTION_CHKLISTBOX_UNCHECK_ALL );
// Update check->EnableIf( ID_ITEMS, IF_NON_EMPTY ); uncheck->EnableIf( ID_ITEMS, IF_NON_EMPTY );
теперь по шагам:
1. список ID
PHP код:
enum { ID_ITEMS, ID_CHECK_ALL, ID_UNCHECK_ALL };
тут все понятно, каждый виджет может иметь уникальный ID, которые мы описываем перед созданием гуи, ес-но есть глобальный список преодпределенных ID - например ID_ANY
2. Создание гуи:
PHP код:
Dialog dlg = DIALOG( caption ); VLAYOUT LABEL( ID_ANY, "Select one of:" ) HLAYOUT CHK_LISTBOX( ID_ITEMS, choices ) VLAYOUT BMP_BUTTON( ID_CHECK_ALL, plus_xpm ); BMP_BUTTON( ID_UNCHECK_ALL, minus_xpm ); END_LAYOUT END_LAYOUT STD_BUTTONS( ID_OK | ID_CANCEL ); END_LAYOUT
тут с помощью макросов создаются сайзеры и виджеты, думаю тут тоже все ясно
3. получение указателей на виджеты
PHP код:
CheckListBox* items = (CheckListBox*) dlg->FindByID( ID_ITEMS ); BitmapButton* check = (BitmapButton*) dlg->FindByID( ID_CHECK_ALL ); BitmapButton* uncheck = (BitmapButton*) dlg->FindByID( ID_UNCHECK_ALL );
4. назначение действий
PHP код:
check->SetAction( ID_ITEMS, ACTION_CHKLISTBOX_CHECK_ALL ); uncheck->SetAction( ID_ITEMS, ACTION_CHKLISTBOX_UNCHECK_ALL );
здесь мы можем привязать одни виджеты к другим - у каждого типа виджетов есть набор действий( которые в принципе дублируют методы этого типа ), мы можем связать дефолтное действие для одного виджета на произвольное действие другого, в том числе можем указать аргумент для действия, например так:
button->SetAction( ID_LABEL, ACTION_LABEL_SET_TEXT, "Sample Text" );
5. автоматическое обновление
PHP код:
// Update check->EnableIf( ID_ITEMS, IF_NON_EMPTY ); uncheck->EnableIf( ID_ITEMS, IF_NON_EMPTY );
здесь мы указываем, что кнопки будут активны только, если виджет с ID - ID_ITEMS не пустой( в данном случае список имеет одну или несколько строк ), варианты:
check->EnableIf( ID_TEXT, IF_VALUE_EQUAL, "Sample" );
check->ShowIf( ID_CHECKBOX, IF_CHECKED );
label->LabelIf( ID_CHECKBOX, IF_CHECKED, "Checked", "Not Checked" );
checkbox->CheckIf( ID_TEXT, IF_NON_EMPTY );
Все это, чтоб не писать лишний раз обработчики событий( ввод текста, нажатие клавиш, выбор чекбокса и т.п. ).
Lester добавил 18.04.2009 в 12:20
насчет:
PHP код:
check->EnableIf( ID_TEXT, IF_VALUE_EQUAL, "Sample" ); check->ShowIf( ID_CHECKBOX, IF_CHECKED ); label->LabelIf( ID_CHECKBOX, IF_CHECKED, "Checked", "Not Checked" ); checkbox->CheckIf( ID_TEXT, IF_NON_EMPTY );
т.к. у многих виджетов будет использоваться практически одно и то же свойство( IF_CHECKED для чекбоксов, IF_NON_EMPTY для полей ввода и т.д. ), то добавил сокращенные варианты:
PHP код:
check->ShowIf( ID_CHECKBOX ); checkbox->CheckIf( ID_TEXT );
ес-но это все будет отражено в моем IDE в редакторе GUI
|
13.04.2009 07:01 |
Lester |
растет пока проект - много переписал, т.к. понял, что ужасно, в частности самый первый пример - массивы:
PHP код:
/**********************************************************************************************/ template< typename T > class LTEXPORT Array { public://////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////// // Define functions types
typedef bool(*ArrayIfFunction)( const T& ); typedef bool(*ArraySortFunction)( const T&, const T& );
public://////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////// // Constructors
Array( ArrayKind kind = ARRAY_SIMPLE ); Array( ArraySortFunction func ); Array( size_t count ); Array( size_t count, T value, ... ); Array( size_t count, T* value ); Array( const std::vector<T>& value ); Array( const Array<T>& value );
public://////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////// // Add/Remove
void Add( const T& item, size_t count = 1 ); void Add( const Array<T>& value );
void Clear( void );
void Insert( size_t index, const T& item, size_t count = 1 ); void Insert( size_t index, const Array<T>& value );
void Prepend( const T& item, size_t count = 1 ); void Prepend( const Array<T>& value );
void Remove( const T& item ); void Remove( const Array<T>& value ); void RemoveAt( size_t index, size_t count = 1 ); void RemoveFirst( size_t count = 1 ); void RemoveIf( ArrayIfFunction func ); void RemoveLast( size_t count = 1 ); void RemoveRange( size_t start, size_t end = size_t( -1 ) );
void Resize( size_t size );
public://////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////// // Items Access
const Array<T>& Copy( size_t start, size_t end = size_t( -1 ) ) const; const Array<T>& CopyIf( ArrayIfFunction func ) const;
size_t Count( void ) const; size_t CountIf( ArrayIfFunction func ) const;
T& Item( size_t index ); T& First( void ); T& Last( void );
const T& Item( size_t index ) const; const T& First( void ) const; const T& Last( void ) const;
public://////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////// // Search
long Index( const T& item ) const; const Array<size_t>& FindAll( const T& item ); long FindFirst( const T& item ); long FindLast( const T& item );
long Index( const Array<T>& values ) const; const Array<size_t>& FindAll( const Array<T>& values ); long FindFirst( const Array<T>& values ); long FindLast( const Array<T>& values );
long FindNext( void );
public://////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////// // Sort
void MakeSorted( bool sorted = true, bool desc = false ); void MakeSorted( ArrayKind kind ); void MakeSorted( ArraySortFunction func );
void Sort( bool desc = false ); void Sort( size_t start, size_t end = size_t( -1 ), bool desc = false ); void Sort( ArraySortFunction func );
public://////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////// // Mutators
void Fill( const T& value, size_t start = 0, size_t end = size_t( -1 ) ); void FillIf( const T& value, ArrayIfFunction func ); void Replace( const T& from, const T& to ); void Replace( const Array<T>& from, const Array<T>& to ); void ReplaceIf( const T& from, const T& to, ArrayIfFunction func ); void Reverse( size_t start = 0, size_t end = size_t( -1 ) ); void Rotate( long count ); void Swap( size_t a, size_t b ); void Swap( size_t start1, size_t count, size_t start2 ); void Swap( Array<T>& value ); void Intersect( Array<T>& value ); void Unique( void );
public://////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////// // Other
bool Contain( const Array<T>& value ) const;
bool Equal( const Array<T>& value ) const; bool Equal( const Array<T>& value, size_t start1, size_t count, size_t start2 = 0 ) const;
const T& Max( void ) const; const T& Max( ArraySortFunction func ) const;
const T& Min( void ); const T& Min( ArraySortFunction func ) const;
public://////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////// // Export/Import
void FromArray( size_t count, T* value ); void FromFile( const String& path ); void FromString( const String& value ); void FromVector( const std::vector<T>& value ); void FromXML( const String& value );
T* ToArray( void ) const; void ToFile( const String& path ); const String& ToString( void ) const; const std::vector<T>& ToVector( void ) const; const String& ToXML( void ) const;
public://////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////// // Operators
Array<T> operator+( const T& value ); Array<T> operator+( const Array<T>& value ); Array<T>& operator+=( const T& value ); Array<T>& operator+=( const Array<T>& value ); Array<T>& operator=( const Array<T>& value ); bool operator==( const Array<T>& value ) const; bool operator!=( const Array<T>& value ) const; T& operator[]( size_t index ); const T& operator[]( size_t index ) const; };
пришлось частично обрезать - ограничение на длину сообщения, вообще учел все замечания zwitter'а и Marchelo, любой массив можно сделать отсортированным, новые элементы будут вставлятся так, что сохранить порядок, ес-но поиск и родственные операции( замена и т.п. ) работают с бинарным алгоритмом, вот архив:
Вложение 98793
в остальном библиотека ощутимо выросла - больше 2Мб кода, не считая тестов, сейчас пишу плагин для поддержки wx, fktk уже на 80% готов, кстати отказался от идеи писать все абсолютно с нуля - за основу взят обрезанный вариант fltk, из которого выдраны все ненужные классы, благо ничего быстрее, удобнее и компактнее( статически слинкованный диалог на fltk весит около 100кб ) под все популярные ОС не найти, а мне немного надо - обработка основных событий и отрисовка примитивов + текста, ес-но плагин для использовния fltk "as is" также останется
|
27.02.2009 12:08 |
Lester |
В связи с загрузкой на работе долго ничего не делал, сейчас понемногу наверстываю( в основном рутинные вещи реализую ), на данный момент в общем виде сделал обработку событий, ничего нового не придумал как сдереть идею MFC и wxWidgets:
PHP код:
BEGIN_EVENT_TABLE( ThemedButton ) EVT_PAINT( ThemedButton::OnPaint ) END_EVENT_TABLE
...
/**********************************************************************************************/ void ThemedButton::OnPaint( Event& event ) { PaintDC dc( this ); dc.SetBrush( RED ); ...
также можно написать:
PHP код:
button->Connect( LT_EVENT_PAINT, EventHandler( ThemedButton::OnPaint ) );
для отправки событий есть глобальные функции:
PHP код:
PostEvent( button, LT_EVENT_PAINT ); PostEvent( button, LT_EVENT_KEY_DOWN, event ); // тут мы должны сами инициализировать переменную event, чтоб передать необходимые данные в обработчик
хотелось бы услышать пожелания по поводу как было бы удобнее организовать обработку событий, да и вообще какие есть варианты
Lester добавил 27.02.2009 в 17:29
Думаю вот реализовать такую фичу, чтоб можно было любому виджету сказать:
dialog->Save() - и он запомнил все свои параметры + параметры всех дочерних виджетов в конфиг приложения, а по dialog->Load() - загружал, т.е. например значения текстовых полей, чекбоксов, скроллов и т.п., ну и ес-но предусмотреть сохранение/загрузку в разные форматы/места, вобщем что-то вроде сериализации
Lester добавил 28.02.2009 в 09:15
Пока делаю виджеты с поддержкой тем, раньше было просто:
PHP код:
button->SetThemeBitmap( BITMAP_BUTTON_PRESSED, Bitmap( "pressed.png" ), 3, 3, 3, 3 ); // 3, 3, 3, 3 - границы по бокам, которые не будут растягиваться
теперь есть Style - набор стилей для всех виджетов, можно получить по имени, сохранить/загрузить в файл и т.п.
Он уже хранит в себе ButtonStyle, CheckButtonStyle etc., каждый из которых также может быть сохранен/загружен
Тут уже сложнее - в каждом стиле для отдельного виджета есть разные элементы, есть два варианта для их отрисовки - текстуры и метафайлы( последовательность шагов - нарисуй линию, нарисуй точку и т.п. ), второе будет быстрее работать, меньше занимать места и следовательно лучше подойдет для слабого железа( например моей n810 ). Когда будет время сделаю редактор стилей.
Каждый виджет с поддержкой стилей по умолчанию использует текущий глобальный стиль, который можно переключать, но ему можно "сказать" использовать другой Style( а также ButtonStyle и т.п. )
Lester добавил 28.02.2009 в 09:35
Пару слов про реализацию Metafile в моем тулките
MetafileDC - такой же DC( DC - то же что и канва ) как и для рисования на экране, в принтер, в ПДФ и т.д., после рисования на нем можно получить Metafile
Metafile - набор операций для рисования, что-то вроде своего формата навроде SVG( кстати добавил поддержку SVG в тулкит - теперь его можно нарисовать на DC )
MetafilePlayer - берет Metafile и рисует на любом DC, т.е. написав функцию, которая нарисует, например, график, мы берем полученный Metafile и отдав его MetafilePlayer + указав DC ( куда хотим сохранить - PDF, Postscript, Latex, ODT, PNG, SVG, HTML и т.д. - в том числе можно просто отрисовать на экране, применяя любой масштаб ) получаем экспорт в нужный формат без всякого усилия со своей стороны
|
31.01.2009 12:16 |
Lester |
кстати теперь Bitmap( "pressed.png" ) может автоматом добавлять картинку в глобальный BitmapRepository( один флаг в SystemSettings - стоит по умолчанию ), и если вызвать этот конструктор еще раз с тем же параметром( для того же файла - идет проверка по абсолютному пути + дате изменения + размеру ) - повторной загрузки и декодирования картинки не будет
|
31.01.2009 12:08 |
Lester |
наверное в ближайшую неделю не буду здесь отписываться - пока занят работой + написанием нового кода, время на исправления( еще раз спасибо Marchello и zwitter за замечания ) не будет, пока добавил новый виджет для отображения TreeItem(s), поддержку текстур для виджетов( потом отдельно опишу, но принцип очень простой - достаточно указать картинку:
Вложение 94081
Вложение 94082
например так:
button->SetThemeBitmap( BITMAP_BUTTON_PRESSED, Bitmap( "pressed.png" ), 3, 3, 3, 3 ); // 3, 3, 3, 3 - границы по бокам, которые не будут растягиваться
и все, также в TreeItem добавлена возможность использовать check-state, а также помимо иконки можно указать функцию для отрисовки - которой отдаются координаты, что дает возможность создавать аимации, без написания дополнительного кода для этого, если же стоит флаг использовать анимации, а функция не указана - будет масштабироваться заданная иконка )
вот видео всего этого:
Вложение 94092 ( переименовал avi в flv - чтоб загрузить на форум, но у меня открывается и с этим расширением )
|
28.01.2009 00:29 |
Lester |
Цитата:
Сообщение от Marchello
Я как любитель gamedev-а всегда склонен к быстродействию кода, поэтому стараюсь обращать внимание на изъяны в этом.
Поэтому методы:
Код:
virtual String GetPath( void ) const = 0;
virtual ArrayString GetGroups( void ) = 0;
virtual ArrayString GetEntries( void ) = 0;
virtual String GetFirstGroup( void ) = 0;
virtual String GetNextGroup( void ) = 0;
// и т.д.
у меня вызывают некоторые волнения (думаю понятно почему), а особенно те которые возвращают ArrayString.
ИМХО лучше возвращать const String& или const String* (это предпочтительней).
А если же предполагается возвращать объекты из стека метода,
то можно даже так написать:
Код:
void GetEntries( ArrayString* s)
{
// тут мы заполняем сразу 's' и никаких стековых объектов
}
выглядит чуть уродливей но эффективно.
|
согласен - теперь возвращается const String& и const ArrayString&, GetEntries и GetGroups теперь принимают в качестве аргумента ArrayString&
Цитата:
Сообщение от Marchello
И еще на счет массива, у тебя все методы виртуальные, а класс определен в виде макроса. То есть, если и наследоваться от него
то только уже от конкретной реализации (с конкретным типом) - тоже не функционально. К тому же объявление методов виртуальными скорости не добавляет. А если отказаться от виртуальности (и от макросовости) - можно с половину методов сделать с inline (правда нужно чтобы эти методы были в h файле, хотя если отказаться от макроса - нужно делать шаблоном, а с шаблонами - все методы будут в h файле )) ).
|
и опять спасибо вариант с шаблоном я пока занес в TODO
|
27.01.2009 09:50 |
Marchello |
Я как любитель gamedev-а всегда склонен к быстродействию кода, поэтому стараюсь обращать внимание на изъяны в этом.
Поэтому методы:
Код:
virtual String GetPath( void ) const = 0;
virtual ArrayString GetGroups( void ) = 0;
virtual ArrayString GetEntries( void ) = 0;
virtual String GetFirstGroup( void ) = 0;
virtual String GetNextGroup( void ) = 0;
// и т.д.
у меня вызывают некоторые волнения (думаю понятно почему), а особенно те которые возвращают ArrayString.
ИМХО лучше возвращать const String& или const String* (это предпочтительней).
А если же предполагается возвращать объекты из стека метода,
то можно даже так написать:
Код:
void GetEntries( ArrayString* s)
{
// тут мы заполняем сразу 's' и никаких стековых объектов
}
выглядит чуть уродливей но эффективно.
И еще на счет массива, у тебя все методы виртуальные, а класс определен в виде макроса. То есть, если и наследоваться от него
то только уже от конкретной реализации (с конкретным типом) - тоже не функционально. К тому же объявление методов виртуальными скорости не добавляет. А если отказаться от виртуальности (и от макросовости) - можно с половину методов сделать с inline (правда нужно чтобы эти методы были в h файле, хотя если отказаться от макроса - нужно делать шаблоном, а с шаблонами - все методы будут в h файле )) ).
|
27.01.2009 01:32 |
Lester |
Интерфейс для хранения структурированных данных:
PHP код:
/**********************************************************************************************/ interface LTAPI I_Container { public://////////////////////////////////////////////////////////////////////////
virtual ~I_Container( void ) {}
public://////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////// // Structure/Navigation
virtual void SetPath( const String& path ) = 0; virtual String GetPath( void ) const = 0; virtual ArrayString GetGroups( void ) = 0; virtual ArrayString GetEntries( void ) = 0;
virtual String GetFirstGroup( void ) = 0; virtual String GetNextGroup( void ) = 0; virtual String GetFirstEntry( void ) = 0; virtual String GetNextEntry( void ) = 0;
virtual size_t GetNumberOfEntries( bool recursive = false ) const = 0; virtual size_t GetNumberOfGroups( bool recursive = false ) const = 0;
virtual bool Delete( const String& path ) = 0; virtual bool DeleteAll( void ) = 0;
virtual bool Exist( const String& path ) const = 0;
virtual bool Rename( const String& oldName, const String& newName ) = 0;
////////////////////////////////////////////////////////////////////////// // Read/Write single value
virtual bool Read( const String& key, long& value, long defVal = 0 ) const = 0; virtual long Read( const String& key, long defVal ) const = 0;
virtual bool Read( const String& key, bool& value, bool defVal = 0 ) const = 0; virtual bool Read( const String& key, bool defVal ) const = 0;
virtual bool Read( const String& key, double& value, double defVal = 0 ) const = 0; virtual double Read( const String& key, double defVal ) const = 0;
virtual bool Read( const String& key, String& value, String defVal = L"" ) const = 0; virtual String Read( const String& key ) const = 0;
virtual bool Read( const String& key, void*& value, size_t& size ) const = 0; virtual bool Read( const String& key, Bitmap& value ) const = 0;
virtual bool Write( const String& key, long value ) = 0; virtual bool Write( const String& key, double value ) = 0; virtual bool Write( const String& key, bool value ) = 0; virtual bool Write( const String& key, const String& value ) = 0; virtual bool Write( const String& key, void* value, size_t size ) = 0; virtual bool Write( const String& key, const Bitmap& value ) = 0;
virtual bool CreateIfAbsent( const String& key, long value ) = 0; virtual bool CreateIfAbsent( const String& key, double value ) = 0; virtual bool CreateIfAbsent( const String& key, bool value ) = 0; virtual bool CreateIfAbsent( const String& key, const String& value ) = 0; virtual bool CreateIfAbsent( const String& key, void* value, size_t size ) = 0; virtual bool CreateIfAbsent( const String& key, const Bitmap& value ) = 0;
////////////////////////////////////////////////////////////////////////// // Read/Write arrays
virtual bool Read( const String& key, ArrayLong& value ) const = 0; virtual bool Read( const String& key, ArrayBool& value ) const = 0; virtual bool Read( const String& key, ArrayDouble& value ) const = 0; virtual bool Read( const String& key, ArrayString& value ) const = 0; virtual bool Read( const String& key, ArrayBitmap& value ) const = 0;
virtual bool Write( const String& key, const ArrayLong& value ) = 0; virtual bool Write( const String& key, const ArrayDouble& value ) = 0; virtual bool Write( const String& key, const ArrayBool& value ) = 0; virtual bool Write( const String& key, const ArrayString& value ) = 0; virtual bool Write( const String& key, const ArrayBitmap& value ) = 0;
////////////////////////////////////////////////////////////////////////// // Other
virtual void Flush( void ) = 0;
public://////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////// // Import/Export
virtual String SaveToString( void ) = 0; virtual void SaveToBuf( void*& value, size_t& size ) = 0; virtual void SaveToFile( const String& path ) = 0;
virtual void LoadFromString( const String& value ) = 0; virtual void LoadFromBuf( void* value, size_t size ) = 0; virtual void LoadFromFile( const String& path ) = 0;
public://////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////// // Options
virtual void SetCreateOnReadIfAbsent( bool value ) = 0; virtual bool GetCreateOnReadIfAbsent( void ) = 0; };
Есть две реализации( которые наследуются от I_ContainerImpl, что позволяет значительно сократить код в них ): TextContainer и XMLContainer, первая хранит все в INI-формате , вторая в XML.
пример кода:
PHP код:
ArrayString list( 3, "A", "B", "C" );
TextContainer container; container.Write( "/Arrays/List", list ); container.Write( "/Simple/Long", 1024 ); String export = container.SaveToString();
list.Clear(); TextContainer container2( export ); container2.Read( "/Arrays/List", list );
|
26.01.2009 17:14 |
Lester |
Цитата:
Сообщение от zwitter
месье хардкодит меню ?
как это пошло....
|
"если уж вы окончательно перешли на французский язык, то называйте меня не месье, а ситуайен, что значит — гражданин"
как один из вариантов - почему нет, как мне по мне - вполне наглядное и легко настраиваемое решение
Lester добавил 26.01.2009 в 18:43
Цитата:
Сообщение от Marchello
Теперь к пану Lesterу, огласите весь список пожалуйста.
В смысле расскажите нам с высоты птичьего полета про ваш тулкит, а не по одному классу. Например список классов с кратчайшем описанием что для чего, ну в таком ключе.. А аудитория будет выбирать наиболее интересные вещи и просить их огласки (вот как с массивом). Это конечно если вы захотите.
|
это будет долго, толком начал я в принципе только в начале январе - многое еще не раз поменяется, ну и реализую я сейчас самые основы( базовые классы и виджеты уже есть, сейчас сайзеры делаю ) но базовое:- я отказался от монолитности - есть LT.so( dll ), он содержит все не связанное с gui напрямую( сайзеры, массивы, хэш-мапы, конфиг, контейнеры и т.д. и т.п. ), вся ОС специфическая часть с помощью интерфейсов вынесена в отдельные( автоматом подгружаемые ) библиотеки, я постарался свести к минимуму то, что там должно быть, что это дает - нет кучи #ifdef для разных ОС и как дополнительный бонус - можно использовать сторонний тулкит для создания виджетов, сейчас у меня есть такое дополнительное расширение для FLTK, будут для Qt, GTK, wxWidgets( это будет мега монстроидально ), Juce, Glui, Fox и т.п., благо писать много для реализации расширения не надо - сейчас расширение для FLTK статично с ним слинкованное весит 260Кб, т.е. всего-лишь указав параметр при инициализации можно получить гуй с использованием лишь winapi, cocoa, xlib, гуй для гнома, гуй для КДЕ и т.п., т.е. такой который впишется в любую ОС и DE, без всякого усилия от разработчика
- упор сделан на минимизации труда при использовании тулкита, т.е. есть набор интефейсов, например рассмотрим I_TreeItem, реализовав который( пронаследовавшись от I_TreeItemImpl, в котором реализована вся логика ) - самому писать практически ничего не надо, можно просто указать виджетам( Tree, ColumnBrowser, List И т.п. ) его в качестве аргумента, и:
- мы автоматом покажем всю структуру
- мы не будем думать о синхронизации, можно иметь свой объект Table, наследованный от TreeItemImpl, если мы его удалим - он автоматом удалится везде из гуя, мы его создадим, указав в конструкторе "папу" - он автоматом добавится в гуй, точно также при изменении его свойств( иконка, подпись )
продолжать можно долго, я наверное все-таки буду писать тут последовательно - как и писал
Lester добавил 26.01.2009 в 18:47
Цитата:
Сообщение от zwitter
ну язвлю, да.
мне не нравится стиль автора.
сделал класс меню ?
ну засунь ты все меню в xml, там пропиши все пункты, иконки, action'ы, hot-key'и.
вгрузи его 1 вызовом и будет щастье.
вот тогда я скажу - да, это удобная штука, с радостью бы использовал
|
сомневаюсь, что это будет:
1. удобнее
2. читабельнее
но такое будет реализовано - причем не только для меню, но и для всего gui, ну и когда через пару месяцев будет рабочий вариант( с устоявшимися классами и интерфейсами ) я с удовольствием приму любые наработки( ес-но с сохранением всех авторских прав - и добавлением их автора в список разработчиков )
Lester добавил 26.01.2009 в 19:03
Цитата:
Сообщение от Marchello
Нужно где-то тулить DECLARE_ARRAY, потом DEFINE_ARRAY, а потом и саму переменную объявить.
Почему бы просто не написать шаблонный класс сразу? (собственно как vector<>).
Тогда пишем CustomArray<MyType> A; и готово. Может я не усмотрел где-то глубинный смысл задумки, но добавлять макросы в проект для каждого нового типа - реально неудобно.
|
тоже вариант - сделаю так отдельно
Цитата:
Сообщение от Marchello
Ладно.., дальше:
Код:
T& operator[]( size_t index );
T operator[]( size_t index ) const;
Почему второй метод (константный) возвращает это, а не const T& ?
Ведь с константной ссылкой мы ничего не поменяем в классе name и в T - и это не нарушит иммутабельность. Вот этот момент хотелось бы подробней знать.
|
да - зевнул, уже исправил, спасибо
Цитата:
Сообщение от Marchello
Потом еще момент, есть конструктор который принимает указатель и кол-во элементов и создает массив.
Так вот ИМХО не помешало бы и такой метод иметь.
Например я создал массив (твой), поработал с ним, удалил все с него,
а потом хочу туда засунуть уже готовый массив (типа int a[64]) -
прийдется уже по одному делать Add(). То есть, можно добавить метод типа:
Код:
void FillFrom(size_t count, T* value );
ну это не критично конечно.
|
добавил - Import называется
Цитата:
Сообщение от Marchello
И последнее, метод Export, строка:
Код:
for( size_t i = 0 ; i < count ; ++i )
res[ i ] = (T) ( mVector[ i ] );
Опять таки, почему (Т) ?
Ведь даже оператор присваивания принимает const name &, а так выходит что создается временный объект - он попадает в оператор присваивания, а потом удаляется.
И тут же момент, обычно Срр-шники юзают new/delete, а тут память выделяется через malloc, если этого не знать а потом вызвать
указателю delete [] - сам знаешь что будет. Но хотя если там написать
res = new T[count] - повызываются лишний раз конструкторы, тоже не хорошо.
|
исправил, надо будет мне пройтись по уже написанному - такие моменты найти и поисправлять, большое спасибо за критику и помощь
Lester добавил 26.01.2009 в 19:54
в том же Array в конструкторе name( size_t count, ... ) исправил на:
Код:
for( size_t i = 0 ; i < count ; ++i )
Add( va_arg( vl, T ) );
было лишнее копирование
|
26.01.2009 17:02 |
Marchello |
(обращение к Лестеру)
Так, посмотрел я массив. Я конечно не гуру Срр, но осмелюсь высказаться ))
Ну сразу - объявление всего класса как макроса конечно интересно...
дебажить невозможно, да и пользоваться неудобно (я чуть-чуть попробовал )) ).
Нужно где-то тулить DECLARE_ARRAY, потом DEFINE_ARRAY, а потом и саму переменную объявить.
Почему бы просто не написать шаблонный класс сразу? (собственно как vector<>).
Тогда пишем CustomArray<MyType> A; и готово. Может я не усмотрел где-то глубинный смысл задумки, но добавлять макросы в проект для каждого нового типа - реально неудобно.
Ладно.., дальше:
Код:
T& operator[]( size_t index );
T operator[]( size_t index ) const;
Почему второй метод (константный) возвращает это, а не const T& ?
Ведь с константной ссылкой мы ничего не поменяем в классе name и в T - и это не нарушит иммутабельность. Вот этот момент хотелось бы подробней знать.
Потом еще момент, есть конструктор который принимает указатель и кол-во элементов и создает массив.
Так вот ИМХО не помешало бы и такой метод иметь.
Например я создал массив (твой), поработал с ним, удалил все с него,
а потом хочу туда засунуть уже готовый массив (типа int a[64]) -
прийдется уже по одному делать Add(). То есть, можно добавить метод типа:
Код:
void FillFrom(size_t count, T* value );
ну это не критично конечно.
И последнее, метод Export, строка:
Код:
for( size_t i = 0 ; i < count ; ++i )
res[ i ] = (T) ( mVector[ i ] );
Опять таки, почему (Т) ?
Ведь даже оператор присваивания принимает const name&, а так выходит что создается временный объект - он попадает в оператор присваивания, а потом удаляется.
И тут же момент, обычно Срр-шники юзают new/delete, а тут память выделяется через malloc, если этого не знать а потом вызвать
указателю delete [] - сам знаешь что будет. Но хотя если там написать
res = new T[count] - повызываются лишний раз конструкторы, тоже не хорошо.
ps. это я смотрел там на первый класс name (а то там внизу еще один есть, дома погляжу...)
|
26.01.2009 13:40 |
zwitter |
ну язвлю, да.
мне не нравится стиль автора.
сделал класс меню ?
ну засунь ты все меню в xml, там пропиши все пункты, иконки, action'ы, hot-key'и.
вгрузи его 1 вызовом и будет щастье.
вот тогда я скажу - да, это удобная штука, с радостью бы использовал
|
26.01.2009 13:06 |
Marchello |
zwitter, ну что ты язвишь человек старается, пишет, хочет поделится своими трудами. Тут можно долго спорить где ООП, а где нет, тут уже зависит от человека который это пишет.
Вот у нас тоже проект - работа с изображениями. Там столько классов, враперы, враперы над враперами, менеджеры, класс команды, класс аргументов для команды, классы валидаторы, куча enum-ов и т.д. И это все нада дернуть чтобы наложить там эффект какой-то для изображения.
Но "в самом низу" этого месива юзается одна несложная либа, вот класс Лестера (который Bitmap) чем-то её напоминает. Я это к чему, что на уровне тулкита - это нормально. Все просто, есть клаас с кучей методов которые делают все что нужно, а в приложении заворачивай этот класс во что угодно - обычно так и делают, чтобы не нарушать архитектуру приложения и не подстраиваться под либу/тулкит.
Теперь к пану Lesterу, огласите весь список пожалуйста.
В смысле расскажите нам с высоты птичьего полета про ваш тулкит, а не по одному классу. Например список классов с кратчайшем описанием что для чего, ну в таком ключе.. А аудитория будет выбирать наиболее интересные вещи и просить их огласки (вот как с массивом). Это конечно если вы захотите.
Я вот тоже например пишу свой "велосипед", не так глобально конечно... больше для развлечения я бы сказал.
Поэтому наезжать с критикой мне даж как-то не удобно что ли, так как
я знаю что мой "велосипед" можно критиковать до бесконечности, но я им пользуюсь, мне нравится
|
26.01.2009 11:53 |
zwitter |
месье хардкодит меню ?
как это пошло....
|
25.01.2009 23:41 |
Lester |
Цитата:
Сообщение от TIGR
если мне не изменяет память - от того что это разные вещи их и разделили в vcl TPicture вроде как вообще просто компонент, который умеет показывать TImage.
|
в том же wx есть два класса wxBitmap, wxImage - но там идет разделение на платформозависимое и платформонезависимое( первое по сути оббертка для HBITMAP, PicHandle, GdkImage, а второе - уже честно хранит все изображение в буфере ), для билдера такое не нужно - т.к. целевая ОС одна
Google говорит, что TPicture класс для хранения изображения, а TImage - виджет, странно, что zwitter привел его в пример
Цитата:
Сообщение от TIGR
в vcl делать над изображениями эффекты наверное так же как и везде... если нужен эффект берешь и пишешь его
|
скорее всего там это через канву делается
Lester добавил 26.01.2009 в 03:57
в продолжении темы про BitmapRepository, в тулките есть большой набор предопределенных ID - например ID_BMP_CUT, ID_BMP_PRINT, ID_BMP_BACK и т.п., стандартый набор иконок для этих ID с разными размерами лежит в отдельном расширении к тулкиту( .so, .dll, .dylib ), можно использовать его( а также иметь несколько таких расширений - и выбирать тему ), можно самому загружать иконки для используемых ID, можно использовать тему иконок KDE/Gnome( в том числе и в виндовс - достаточно указать путь ) - для них есть десятки отличных тем, т.е. можно писать, например, так:
PHP код:
Menu menu; menu.Add( ID_ACTION_NEW, "New...", , CTRL + 'N' )->SetBitmap( theBitmapRepository->GetBitmap( ID_BMP_NEW, 16 ) ); menu.Add( ID_ACTION_OPEN, "Open...", CTRL + 'O' )->SetBitmap( theBitmapRepository->GetBitmap( ID_BMP_OPEN, 16 ) ); menu.Add( ID_ACTION_PREVIEW, "Preview..." )->SetBitmap( theBitmapRepository->GetBitmap( ID_BMP_PREVIEW, 16 ) ); menu.Popup();
и вообще не думать об загрузке иконок
Lester добавил 26.01.2009 в 08:52
добавил макрос - BITMAP, теперь пример выглядит так:
PHP код:
Menu menu; menu.Add( ID_ACTION_NEW, "New...", , CTRL + 'N' )->SetBitmap( BITMAP( ID_BMP_NEW, 16 ) ); menu.Add( ID_ACTION_OPEN, "Open...", CTRL + 'O' )->SetBitmap( BITMAP( ID_BMP_OPEN, 16 ) ); menu.Add( ID_ACTION_PREVIEW, "Preview..." )->SetBitmap( BITMAP( ID_BMP_PREVIEW, 16 ) ); menu.Popup();
Lester добавил 26.01.2009 в 11:40
добавил возможность связать action с bitmap, для всех стандартных это можно включить( при старте приложения ) через:
theSystemOptions->Write( "/Actions/EnableDefaultAutoBitmaps", true );
для своих actions можно создать связку через:
AssignActionBitmap( MY_ID_ACTION_NEW, MY_ID_BMP_NEW );
пока это тестовый вариант, потом подумаю как сделать( назвать ) лучше
пример:
PHP код:
theSystemOptions->Write( "/Actions/EnableDefaultAutoBitmaps", true );
// Нестандартные ID AssignActionBitmap( vsID_ACTION_NEW_DATABASE, vsID_BMP_NEW_DATABASE ); AssignActionBitmap( vsID_ACTION_OPEN_DATABASE, vsID_BMP_OPEN_DATABASE ); ...
MenuBar* bar = new MenuBar( this ); ////////////////////////////////////////////////////////////////////////// // File Menu* menu = bar->Add( "File" ); menu->Add( ID_ACTION_NEW_WINDOW, "New Window", CTRL + SHIFT + 'N' ); menu->Add( ID_ACTION_CLOSE_WINDOW, "Close Window", CTRL + SHIFT + 'W' ); menu->Add( ID_ACTION_CLOSE_TAB, "Close Tab", CTRL + 'W' ); menu->AddSeparator(); //--------------------------------------------------------------------- menu->Add( ID_ACTION_SAVE_FILE, "Save", CTRL + 'S' ); menu->Add( ID_ACTION_SAVE_ALL_FILES, "Save All", CTRL + SHIFT + 'S' ); menu->AddSeparator(); //--------------------------------------------------------------------- menu->Add( vsID_ACTION_NEW_DATABASE, "New Database...", CTRL + 'N' ); menu->Add( vsID_ACTION_OPEN_DATABASE, "Open Database...", CTRL + 'O' ); menu->Add( -1, "Open Recent Database" ); menu->Add( vsID_ACTION_CLOSE_DATABASE, "Close Database", CTRL + ALT + 'W' ); menu->Add( vsID_ACTION_CLOSE_ALL_DATABASES, "Close All Databases" ); menu->AddSeparator(); //--------------------------------------------------------------------- menu->Add( ID_ACTION_IMPORT, "Import..." ); menu->Add( ID_ACTION_EXPORT, "Export..." ); menu->AddSeparator(); //--------------------------------------------------------------------- Menu* dumpMenu = menu->AddMenu( "Dump Database..." ); dumpMenu->Add( vsID_ACTION_DUMP_SQL, "SQL..." ); dumpMenu->Add( vsID_ACTION_DUMP_XML, "XML..." ); Menu* loadMenu = menu->AddMenu( "Load Dump..." ); loadMenu->Add( vsID_ACTION_LOAD_SQL, "SQL..." ); loadMenu->Add( vsID_ACTION_LOAD_XML, "XML..." ); menu->AddSeparator(); //--------------------------------------------------------------------- menu->Add( ID_ACTION_PRINT_SETUP, "Page Setup..." ); menu->Add( ID_ACTION_PRINT, "Print...", CTRL + 'P' ); menu->Add( ID_ACTION_PRINT_PREVIEW, "Print preview" ); menu->AddSeparator(); //--------------------------------------------------------------------- menu->Add( ID_ACTION_QUIT, "Exit", ALT + 'X' );
форматирование как всегда побилось
|
25.01.2009 22:35 |
TIGR |
Цитата:
Сообщение от Lester
как по мне наоборот, в данном случае есть только один объект - изображение и делить тут нечего, и расскажите плз:
1. смысл разделения на TBitmap, TPicture, TImage( особенно для того кто пользуется ими - так удобнее? )
2. как вырезать из картинки в VCL подкартинку( ее произвольную часть ) , как отразить изображение, повернуть, размыть и т.д., т.е. те действия которые я добавил в класс
|
если мне не изменяет память - от того что это разные вещи их и разделили в vcl TPicture вроде как вообще просто компонент, который умеет показывать TImage.
в vcl делать над изображениями эффекты наверное так же как и везде... если нужен эффект берешь и пишешь его
|
25.01.2009 19:46 |
Lester |
ну и ес-но раз есть изображения, то должно быть удобное хранилище для них:
PHP код:
/**********************************************************************************************/ interface LTAPI I_BitmapRepository { public://////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////// // Add bitmaps
virtual void AddBitmap( const Bitmap& bmp, const String& name ) = 0; virtual void AddBitmap( const Bitmap& bmp, size_t id, size_t size = 0 ) = 0; virtual void AddBitmap( const Bitmap& bmp, const String& name, size_t id, size_t size = 0 ) = 0;
////////////////////////////////////////////////////////////////////////// // Load from files
virtual void LoadFromDir( const String& path, const String& mask = "*.*" ) = 0; virtual void SmartLoad( const String& path, size_t id ) = 0;
virtual void LoadFromFile( const String& name ) = 0; virtual void LoadFromFile( const String& name, size_t id, size_t size = 0 ) = 0;
virtual void SetBasePath( const String& path ) = 0;
////////////////////////////////////////////////////////////////////////// // Retrieve bitmaps
virtual bool IsExist( size_t id, size_t size = 0 ) = 0; virtual bool IsExist( const String& name ) = 0;
virtual const Bitmap& GetBitmap( size_t id, size_t size = 0 ) = 0; virtual const Bitmap& GetBitmap( const String& name ) = 0;
////////////////////////////////////////////////////////////////////////// // Combine/Modify bitmaps
virtual void GenerateBitmap( size_t id, size_t idSource, size_t idAddedFirst = 0, size_t idAddedSecond = 0, size_t idAddedThird = 0 ) = 0;
virtual void GenerateDisabledBitmap( size_t id, size_t idSource ) = 0; };
это интерфейс, в тулките есть его реализация - BitmapRepository, также есть глобальный объект theBitmapRepository, который создается автоматом при старте приложения и может быть доступен из любого места в программе
доступ к картинкам воможен по:
PHP код:
theBitmapRepository->AddBitmap( Bitmap( "test.png"), "test" ); Bitmap bmp = theBitmapRepository->GetBitmap( "test" );
PHP код:
theBitmapRepository->AddBitmap( Bitmap( "test.png"), ID_BMP_TEST ); Bitmap bmp = theBitmapRepository->GetBitmap( ID_BMP_TEST );
PHP код:
theBitmapRepository->AddBitmap( Bitmap( "test_16.png"), ID_BMP_TEST, 16 ); theBitmapRepository->AddBitmap( Bitmap( "test_32.png"), ID_BMP_TEST, 32 ); Bitmap bmp32 = theBitmapRepository->GetBitmap( ID_BMP_TEST, 32 );
некоторые методы:- LoadFromDir( const String& path, const String& mask = "*.*" )
загружает все изображения из папки, потом изображения можно получить по имени, например - test_16- SmartLoad( const String& path, size_t id )
небольшая отсебятина, часто надо иметь одно изображения разных размеров, и чтоб не писать:
PHP код:
theBitmapRepository->AddBitmap( Bitmap( "test_16.png"), ID_BMP_TEST, 16 ); theBitmapRepository->AddBitmap( Bitmap( "test_32.png"), ID_BMP_TEST, 32 ); theBitmapRepository->AddBitmap( Bitmap( "test_48.png"), ID_BMP_TEST, 48 ); ...
можно один раз написать:
PHP код:
theBitmapRepository->SmartLoad( "test_*.png", ID_BMP_TEST );
будут добавлены все файлы по маске - размер будет взят из части имени на месте *см. выше про объединение нескольких изображений в одно
|
25.01.2009 03:21 |
Lester |
Цитата:
Сообщение от zwitter
каша полнейшая. не торт совершенно
проповедники ООП плачут крокодильими слезами.
нафига все было сбивать в 1 класс ?
в том же VCL есть три разных понятия - TBitmap, TPicture, TImage
вынесите все функции нафиг из класса, ООП тут нет.
|
как по мне наоборот, в данном случае есть только один объект - изображение и делить тут нечего, и расскажите плз:
1. смысл разделения на TBitmap, TPicture, TImage( особенно для того кто пользуется ими - так удобнее? )
2. как вырезать из картинки в VCL подкартинку( ее произвольную часть ) , как отразить изображение, повернуть, размыть и т.д., т.е. те действия которые я добавил в класс
насчет методов - да, есть смысл убрать операции которые возвращают новые изображения, и оставить только ...Self, ес-но переименовав, так и сделаю - будет компактнее и выглядеть опрятнее
Lester добавил 25.01.2009 в 04:29
сейчас выглядит как:
PHP код:
/**********************************************************************************************/ class LTAPI Bitmap { public:////////////////////////////////////////////////////////////////////////// // TODO: AUTO register/unregister in repository
Bitmap( void ); Bitmap( const Bitmap& bmp ); Bitmap( const Bitmap& bmp, const Rect& rect ); Bitmap( size_t width, size_t height ); Bitmap( const String& path, BitmapType type = AUTO ); Bitmap( void* data, size_t size, BitmapType type = AUTO ); Bitmap( const char* const* xpm );
virtual ~Bitmap( void );
public://////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////// // Information
size_t GetWidth( void ) const; size_t GetHeight( void ) const;
bool IsOk( void ) const;
////////////////////////////////////////////////////////////////////////// // Load and save
bool LoadData( void* data, size_t size, BitmapType type = AUTO ); bool LoadFile( const String& path, BitmapType type = AUTO );
bool SaveData( void*& data, size_t& size, BitmapType type = PNG ) const; bool SaveFile( const String& path, BitmapType type = AUTO ) const;
////////////////////////////////////////////////////////////////////////// // Filters
Bitmap& Blur( size_t radius );
Bitmap& ColourReduction( size_t colours = 236 ); Bitmap& ConvertToGreyscale( void ); Bitmap& ConvertToMono( void );
Bitmap GetSubBitmap( const Rect& rect ) const;
Bitmap& MirrorHorizontal( void ); Bitmap& MirrorVertical( void );
Bitmap& Scale( size_t width, size_t height, bool highQuality = true );
Bitmap& Resize( size_t width, size_t height, Colour cl = BLACK );
Bitmap& Rotate( size_t angle, size_t x, size_t y, bool highQuality = true );
Bitmap& Rotate90( bool clockwise = true ); Bitmap& RotateHue( size_t angle );
////////////////////////////////////////////////////////////////////////// // Transparency and mask
void CreateMaskFromBitmap( const Bitmap& mask, Colour maskColour ); void CreateMaskFromColour( Colour mask ); void DeleteMask( void );
bool HasAlpha( void ) const; bool HasMask( void ) const; bool IsTransparent( size_t x, size_t y, uchar threshold = 128 ) const;
void ConvertAlphaToMask( uchar threshold = 128 ); void InitAlpha( void );
Colour GetMaskColour( void ) const;
////////////////////////////////////////////////////////////////////////// // Pixels
uchar GetAlpha( size_t x, size_t y ) const; Colour GetColour( size_t x, size_t y ) const;
void Replace( Colour c1, Colour c2 );
void SetAlpha( size_t x, size_t y, uchar value );
void SetColour( size_t x, size_t y, Colour value );
const uchar* GetData( void ) const;
public://////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////// // Operators
Bitmap& operator=( const Bitmap& value ); bool operator==( const Bitmap& value ) const;
protected://////////////////////////////////////////////////////////////////////////
BitmapData* mpData; };
Lester добавил 25.01.2009 в 13:10
кстати разделение таки будет, но разумное - будет BitmapEx( туда будут вынесены ColourReduction, RotateHue и Rotate ), в котором будут реализованы изменения яркости/контрастности, дополнительные фильтры( скопирую алгоритмы из gimp ) и т.п., то что надо редко, но может пригодится, например для создания анимаций
Lester добавил 25.01.2009 в 13:41
ну и забыл добавить - пути в именах файлов для загрузки могут быть относительными. По умолчанию от папки программы, но базовый путь может быть выставлен через SetResourcesPath:
PHP код:
// Show splash SetResourcesPath( "resources" ); // так-же может быть относительным, ес-но от папки программы Splash splash( Bitmap( "splash.png" ) ); ... Bitmap bmp( "sample/sample.gif" ); // будет читать из resources/sample/sample.gif
Lester добавил 25.01.2009 в 13:56
добавил еще операторы "+" и "+=", может пригодится, например есть набор иконок для объектов( БД, таблица и т.п. ), надо еще для тех же объектов иконки - добавить/удалить/флушить/заблокировать/разблокировать и т.п., чтоб не иметь зоопарк иконок в папке ресурсов создаем только иконки самих объектов + отдельные( с маской ) иконки - добавить/удалить/флушить/заблокировать/разблокировать, а потом накладываем одни на другие, например так:
PHP код:
Bitmap dbIcon( "db.png" ); Bitmap tableIcon( "table.png" ); ... Bitmap addIcon( "add.png" ); Bitmap deleteIcon( "delete.png" ); ... Bitmap addDbIcon = dbIcon + addIcon; Bitmap addTableIcon = tableIcon + addIcon; ...
|
25.01.2009 01:18 |
zwitter |
каша полнейшая. не торт совершенно
проповедники ООП плачут крокодильими слезами.
нафига все было сбивать в 1 класс ?
в том же VCL есть три разных понятия - TBitmap, TPicture, TImage
вынесите все функции нафиг из класса, ООП тут нет.
|
25.01.2009 01:04 |
Lester |
Цитата:
Сообщение от zwitter
какой сакральный смысл у функции IsOk ?
|
простой - имеем ли мы дело с рабочим изображением, предположим ты напишешь так:
Bitmap bmp( "non-exist.png" ); // а такого файла нет
тогда IsOk вернет false
|
25.01.2009 01:00 |
zwitter |
какой сакральный смысл у функции IsOk ?
|
25.01.2009 00:17 |
Lester |
насчет массивов - будем считать, что разобрались( бинарный поиск и SortedArray занесены в TODO и обязательно будут реализованы ), пошли дальше...
Bitmap( класс для работы с изображениями )
PHP код:
/**********************************************************************************************/ class LTAPI Bitmap { public:////////////////////////////////////////////////////////////////////////// // TODO: AUTO register/unregister in repository
Bitmap( void ); Bitmap( const Bitmap& bmp ); Bitmap( const Bitmap& bmp, const Rect& rect ); Bitmap( size_t width, size_t height ); Bitmap( const String& path, BitmapType type = AUTO ); Bitmap( void* data, size_t size, BitmapType type = AUTO ); Bitmap( const char* const* xpm );
virtual ~Bitmap( void );
public://////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////// // Information
size_t GetWidth( void ) const; size_t GetHeight( void ) const;
bool IsOk( void ) const;
////////////////////////////////////////////////////////////////////////// // Load and save
bool LoadData( void* data, size_t size, BitmapType type = AUTO ); bool LoadFile( const String& path, BitmapType type = AUTO );
bool SaveData( void*& data, size_t& size, BitmapType type = PNG ) const; bool SaveFile( const String& path, BitmapType type = AUTO ) const;
////////////////////////////////////////////////////////////////////////// // Filters
Bitmap Blur( size_t radius ) const; Bitmap& BlurSelf( size_t radius );
Bitmap BlurHorizontal( size_t radius ) const; Bitmap& BlurHorizontalSelf( size_t radius );
Bitmap BlurVertical( size_t radius ) const; Bitmap& BlurVerticalSelf( size_t radius );
Bitmap ColourReduction( size_t colours = 236 ) const; Bitmap& ColourReductionSelf( size_t colours = 236 );
Bitmap ConvertToGreyscale( void ) const; Bitmap& ConvertToGreyscaleSelf( void );
Bitmap ConvertToMono( void ) const; Bitmap& ConvertToMonoSelf( void );
Bitmap GetSubBitmap( const Rect& rect ) const;
Bitmap MirrorHorizontal( void ) const; Bitmap& MirrorHorizontalSelf( void );
Bitmap MirrorVertical( void ) const; Bitmap& MirrorVerticalSelf( void );
Bitmap Scale( size_t width, size_t height, bool highQuality = true ) const;
Bitmap& ScaleSelf( size_t width, size_t height, bool highQuality = true );
Bitmap Resize( size_t width, size_t height, Colour cl = BLACK ) const;
Bitmap& ResizeSelf( size_t width, size_t height, Colour cl = BLACK );
Bitmap Rotate( size_t angle, size_t x, size_t y, bool highQuality = true ) const;
Bitmap& RotateSelf( size_t angle, size_t x, size_t y, bool highQuality = true );
Bitmap RotateHue( size_t angle ) const; Bitmap& RotateHueSelf( size_t angle );
Bitmap Rotate90( bool clockwise = true ) const; Bitmap& Rotate90Self( bool clockwise = true );
////////////////////////////////////////////////////////////////////////// // Transparency and mask
void CreateMaskFromBitmap( const Bitmap& mask, Colour maskColour ); void CreateMaskFromColour( Colour mask ); void DeleteMask( void );
bool HasAlpha( void ) const; bool HasMask( void ) const; bool IsTransparent( size_t x, size_t y, uchar threshold = 128 ) const;
void ConvertAlphaToMask( uchar threshold = 128 ); void InitAlpha( void );
Colour GetMaskColour( void ) const; uchar GetMaskRed( void ) const; uchar GetMaskGreen( void ) const; uchar GetMaskBlue( void ) const;
////////////////////////////////////////////////////////////////////////// // Pixels
uchar GetAlpha( size_t x, size_t y ) const; Colour GetColour( size_t x, size_t y ) const; uchar GetRed( size_t x, size_t y ) const; uchar GetGreen( size_t x, size_t y ) const; uchar GetBlue( size_t x, size_t y ) const;
void Replace( Colour c1, Colour c2 ); void Replace( uchar r1, uchar g1, uchar b1, uchar r2, uchar g2, uchar b2 );
void SetAlpha( size_t x, size_t y, uchar value );
void SetColour( size_t x, size_t y, Colour value );
const uchar* GetData( void ) const;
public://////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////// // Operators
Bitmap& operator=( const Bitmap& value ); bool operator==( const Bitmap& value ) const; protected://////////////////////////////////////////////////////////////////////////
BitmapData* mpData; };
как всегда форматирование побилось
поддерживаются GIF, PNG, BMP, XPM, TGA, JPEG, PCX, TIFF, загрузка и сохранение в файл/буффер, базовые фильтры - все остальные будут реализованы отдельно, работа с альфа-каналом и маской, данный класс используется везде где надо хранить и передавать изображения( например иконки для gui )
может у кого-то есть предложения по данному классу( например чего-то не хватает )
|
24.01.2009 14:29 |
Lester |
я уже сказал - хорош гадить, думай, что хочешь, но не мешай - я буду тут шаг за шагом все описывать, начал ес-но с основ, просьба или писать по сути, или не писать вообще
потому по сути:
"обоснуйте" - да хотя бы нет проверок на индексы( у меня тоже нет - добавлю, это легко - сейчас я другое делаю ), ну и сложение двух векторов, вставка 10 одинаковых значений в начало и т.п. - уже отдельные операции, да и банально:
Код:
ArrayString array;
array.Add( "item", 10 );
array.Prepend( "1" );
array.Insert( 1, "2" );
более читабельно чем:
Код:
vector<String>array;
for( size_t i = 0 ; i < 10 ; ++i )
array.push_back( "item" );
vector<String>::iterator it = array.begin();
array.insert( it , "1" );
array.insert( ++it , "2" );
"я конечно понимаю, что каждый уважающий себя начинающий программист
обязан написать свой стек, списки и библиотеку для рисования окошек. "
да - я прошел это еще с zx48k, сейчас я хочу написать прежде всего удобный тулкит, насколько это мне удастся - будем судить потом, сейчас я жду только конструктивной критики
Lester добавил 24.01.2009 в 15:49
Цитата:
Сообщение от zwitter
нахрена мне ваша заготовка, если вы один хрен инкапсулируете вектор и лишь закрываете мне многие полезности вектора ?
как мне отсортировать массив структур в вашем тулките ?
где двоичный поиск ?
ваша операция Index ищет первое вхождение в массиве ?
где операция подсчета количества элементов в массиве ?
|
"нахрена мне ваша заготовка, если вы один хрен инкапсулируете вектор и лишь закрываете мне многие полезности вектора ?" - какие многие полезности?
"как мне отсортировать массив структур в вашем тулките ?" - странно, но Sort()
"ваша операция Index ищет первое вхождение в массиве ?" - за это спасибо, расширю поиск
"где операция подсчета количества элементов в массиве ?" - Count(), вы опять невнимательны
Lester добавил 24.01.2009 в 16:05
добавил:
Код:
virtual long FindFirst( const T& item );
virtual long FindNext( void );
virtual ArrayULong FindAll( const T& item );
Lester добавил 24.01.2009 в 16:24
Цитата:
Сообщение от zwitter
и по какому полю из структуры оно сортирует ?
|
надо задать оператор сравнения, например так:
/************************************************** ********************************************/
struct MyStruct
{
String name;
String lastName;
public://////////////////////////////////////////////////////////////////////////
bool operator<( const MyStruct& value ) const
{
return name < value.name;
}
bool operator>( const MyStruct& value ) const
{
return name > value.name;
}
};
вопрос понял, добавлю еще один вариант sort с параметром в виде функции для сравнения
Lester добавил 24.01.2009 в 16:26
форматирование опять побилось - сорри
Lester добавил 24.01.2009 в 16:31
"где двоичный поиск?" - тоже согласен, думаю надо будет ввести новый тип SortedArray, плюс, чтоб обычный Array умел помнить - отсортирован он или нет, и если да - делал быстрый поиск, вот за такую критику спасибо - на все вопросы сразу я ответить не могу( долго ), а по отдельности( как сейчас про массивы ) - буду только благодарен
|
24.01.2009 13:57 |
zwitter |
Цитата:
Сообщение от Lester
Используясь stl, boost и различные тулкиты я пришел к выводам:
1. stl не всегда удобен( гениальный вывод - я знаю )
|
обоснуйте
Цитата:
Сообщение от Lester
2. при написании gui нужно использовать шаблоны
|
вот тут поподробнее.
Цитата:
Сообщение от Lester
3. все существующие концепции model-view громоздки, неудобны и также должны иметь шаблоны - у меня есть идеи как сделать все проще и вместе с тем сэкономить массу времени на синхронизацию данных и gui
|
контроллер забыли?
идеи в студию.
Цитата:
Сообщение от Lester
4. во многих тулкитах нет банальных вещей - например удобного репозитория картинок, контейнеров для хранения данных в виде VFS и т.д.
|
VCL: TImageList
про VFS подробнее пожалуйста. что вам надо и где хранить ?
Цитата:
Сообщение от Lester
5. нет тулкита для С++, который бы хорошо работал и на ПК( для разных ОС ) и на КПК( например на моей н810 - wxWidgets жутко тормозит и страшно выглядит ), точнее есть один - Qt, но он проприетарный( его купила Nokia ) и может быть закрыт в любой момент
|
не закроют, наоборот, открывают еще шире.
Цитата:
Сообщение от Lester
6. я для себя написал реализацию dc с одним интерфейсом для PDF, HTML, SVG, LaTeX, PS и т.п. - т.е. одна и та же функция теперь легко может рисовать не только на экране, но и в PDF, HTML, на принтер( ну это понятно ) и т.д., точно также у меня есть другие полезные заготовки( например унифицированная( через VFS ) работа с rar, tar, zip и т.д. ), которые могут пригодится тем, кто не хочет искать стороние библиотеки и потом прикручивать их "сбоку"
|
что такое DC ? постоянный ток ? клиент сети Direct Connect ?
я конечно рад что вы для себя открыли что-то похожее на Apache FOP, но только не надо пафоса с перечислением всех форматов которые умеет экспортировать сторонняя библиотека.
Цитата:
Сообщение от Lester
естественно заранее предопределены в самом тулките
ArrayBool, ArrayDouble, ArrayLong, ArrayID, ArrayString, ArrayBitmap, ArrayPtrVoid
|
vector<bool>
vector<double>
vector<long>
vector<ID???> - WTF ?
vector<string>
vcl: TImageList
....
блджад, где обещанные инновации ?
нахрена мне ваша заготовка, если вы один хрен инкапсулируете вектор и лишь закрываете мне многие полезности вектора ?
как мне отсортировать массив структур в вашем тулките ?
где двоичный поиск ?
ваша операция Index ищет первое вхождение в массиве ?
где операция подсчета количества элементов в массиве ?
Цитата:
Сообщение от Lester
какие предложения для расширения/изменения класса?
|
сложить в дальнюю папку
я конечно понимаю, что каждый уважающий себя начинающий программист обязан написать свой стек, списки и библиотеку для рисования окошек.
ничего, это пройдет
|
24.01.2009 13:40 |
Lester |
Цитата:
Сообщение от zwitter
QT - проприетарный ? ололошечки
уже все пописялись от радости что QT, который будет выпущен в марте, будет под LGPL.
zwitter добавил 24.01.2009 в 14:22
зыж - надписи PHP код забавляют да
|
спасибо, что нагадил, если по делу ничего нет - проходи
вот кстати .h и .cpp для array
Вложение 93531
|
24.01.2009 13:20 |
zwitter |
QT - проприетарный ? ололошечки
уже все пописялись от радости что QT, который будет выпущен в марте, будет под LGPL.
zwitter добавил 24.01.2009 в 14:22
зыж - надписи PHP код забавляют да
|
24.01.2009 12:29 |
Lester |
Less Toolkit
Используясь stl, boost и различные тулкиты я пришел к выводам:
1. stl не всегда удобен( гениальный вывод - я знаю )
2. при написании gui нужно использовать шаблоны
3. все существующие концепции model-view громоздки, неудобны и также должны иметь шаблоны - у меня есть идеи как сделать все проще и вместе с тем сэкономить массу времени на синхронизацию данных и gui
4. во многих тулкитах нет банальных вещей - например удобного репозитория картинок, контейнеров для хранения данных в виде VFS и т.д.
5. нет тулкита для С++, который бы хорошо работал и на ПК( для разных ОС ) и на КПК( например на моей н810 - wxWidgets жутко тормозит и страшно выглядит ), точнее есть один - Qt, но он проприетарный( его купила Nokia ) и может быть закрыт в любой момент
6. я для себя написал реализацию dc с одним интерфейсом для PDF, HTML, SVG, LaTeX, PS и т.п. - т.е. одна и та же функция теперь легко может рисовать не только на экране, но и в PDF, HTML, на принтер( ну это понятно ) и т.д., точно также у меня есть другие полезные заготовки( например унифицированная( через VFS ) работа с rar, tar, zip и т.д. ), которые могут пригодится тем, кто не хочет искать стороние библиотеки и потом прикручивать их "сбоку"
ну и т.д.
данный тулкит ес-но разделен на gui и non-gui, здесь я буду шаг за шагом описывать то что делаю( сделал ), с целью получить максимально конструктивной критики
|