Перейти к содержанию
Fire Monkey от А до Я

Камышев Александр

Пользователи
  • Постов

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

  • Посещение

  • Победитель дней

    9

Активность репутации

  1. Like
    Камышев Александр получил реакцию от Rusland в Использование TClientSocket (old school )   
    Задача поднять старый (теплый ламповый) проект CBuilder 6 под Виндовс в RAD Studio.
    Просто открыл файл проекта, практически все подтянулось с небольшими изменениями в путях include. Кроме TClientSocket, нет такого визуального компонента.
    Компонента нет, но библиотеки в RAD Studio оставили. Подключил #include <ScktComp.hpp>, создал динамически TClientSocket, определил события - проект поднялся малой кровью.
    #include <ScktComp.hpp> TClientSocket *сlient = new TClientSocket(NULL); сlient->OnConnect = ClientConnect; сlient->OnDisconnect = ClientDisconnect; сlient->OnError = ClientError; сlient->OnRead = ClientRead; Аналогично можно пользоваться TServerSocket. Может кому пригодится.
  2. Like
    Камышев Александр получил реакцию от Ingalime в Использование TClientSocket (old school )   
    Задача поднять старый (теплый ламповый) проект CBuilder 6 под Виндовс в RAD Studio.
    Просто открыл файл проекта, практически все подтянулось с небольшими изменениями в путях include. Кроме TClientSocket, нет такого визуального компонента.
    Компонента нет, но библиотеки в RAD Studio оставили. Подключил #include <ScktComp.hpp>, создал динамически TClientSocket, определил события - проект поднялся малой кровью.
    #include <ScktComp.hpp> TClientSocket *сlient = new TClientSocket(NULL); сlient->OnConnect = ClientConnect; сlient->OnDisconnect = ClientDisconnect; сlient->OnError = ClientError; сlient->OnRead = ClientRead; Аналогично можно пользоваться TServerSocket. Может кому пригодится.
  3. Like
    Камышев Александр получил реакцию от Ingalime в Сглаживание при рисовании в буфер bitmap   
    протестировал 3 варианта:
    1. правка FMX.Graphics.pas как указано выше
    2. пишу на с++, можно исправить файл FMX.Graphics.hpp
     заменить код 
    __property TCanvasQuality Quality = {read=FQuality, nodefault}; на 
    __property TCanvasQuality Quality = {read=FQuality, write=FQuality, nodefault}; после этого можно 
    bmp_buf->Canvas->Quality = TCanvasQuality::HighQuality; 3. Создать новую канву как указано выше
    TCanvas *MyCanvas = TCanvasManager::CreateFromBitmap( bmp_buf, TCanvasQuality::HighQuality ); во всех трех случаях свойство Quality под debug имеет значение HighQuality, проверял перед DrawPath:
    bool b = MyCanvas->Quality == TCanvasQuality::HighQuality; и во всех вариантах эффекта не было...
    неспроста Quality для формы нужно ставить в design-time
    что происходит при сборке, из-чего включается антиалиасинг?
    .
  4. Like
    Камышев Александр отреагировална ENERGY в Сглаживание при рисовании в буфер bitmap   
    Итак на Android и iOS нет сглаживания при отрисовке примитивов (линий, кругов, вектора).
    Метод 1 (Native Draw, Delphi ONLY ) - лучший и простой. 
    На Canvas PaintBox рисуем как обычно.
    Если нужно нарисовать на Canvas Bitmap'a, а не на PaintBox, тогда нужно правильно подготовить Bitmap: 
    if Scene <> nil then lScale := Scene.GetSceneScale else lScale := 1; // fBitmap.BitmapScale := lScale; //это только для DrawPath fBitmap.SetSize(Ceil(Width * lScale), Ceil(Height * lScale) );  
    Все детали здесь, также там ссылка на сайт (используйте гугл переводчик)
    https://github.com/OneChen/FMXNativeDraw
    Если нужно сохранить в Bitmap, то делаем PaintBox.MakeScreenshot (TControl.PaintTo) в результате получаем сглаженный Bitmap. Кстати вызвать PaintTo не получится в Paint и Afterpaint методах текущего контрола - будет циклический вызов Paint и в результате переполнение стэка, нужно делать это в AfterPaint формы или фрейма. 
    Метод 2.
    http://riversoftavg.com/blogs/index.php/2016/06/09/use-supersampling-for-offscreen-bitmaps-on-delphi-mobile/
  5. Like
    Камышев Александр получил реакцию от Anatoliy в Ссылка на "Политика конфиденциальности"   
    Спасибо за наводку, вот это помогло:
     
  6. Like
    Камышев Александр отреагировална Kitty в Открыть ссылку   
    Дополнительно найдено:
    #if defined(__ANDROID__) #include <Androidapi.JNI.JavaTypes.hpp> #include <Androidapi.JNI.GraphicsContentViewText.hpp> #include <Androidapi.JNI.Net.hpp> #include <Androidapi.Helpers.hpp> #include <FMX.Helpers.Android.hpp> #elif defined(__APPLE__) #include <iOSapi.Foundation.hpp> #include <Macapi.Helpers.hpp> #include <FMX.Helpers.iOS.hpp> #elif defined(MSWINDOWS) #include <shellapi.h> endif bool __fastcall OpenURL(const String &AURL) { #if defined(__ANDROID__) _di_JIntent Intent = TJIntent::JavaClass->init(TJIntent::JavaClass->ACTION_VIEW, TJnet_Uri::JavaClass->parse(StringToJString(AURL))); try { SharedActivity()->startActivity(Intent); return true; } catch (const Exception &) { return false; } #elif defined(__APPLE__) _di_NSURL NSU = StrToNSUrl(AURL); if (SharedApplication()->canOpenURL(NSU)) return SharedApplication()->openURL(NSU); else return false; #elif defined(MSWINDOWS) SHELLEXECUTEINFOW sei = {0}; sei.cbSize = sizeof(sei); sei.lpFile = AURL.c_str(); sei.nShow = SH_SHOWNORMAL; return ShellExecuteEx(&sei); #else return false; #endif } void __fastcall TForm1::Text1Click(TObject *Sender) { OpenURL(L"http://fire-monkey.tu"); }  
  7. Like
    Камышев Александр отреагировална enatechno в Ссылка на "Политика конфиденциальности"   
    Либо использовать TWebBrowser,  либо вызвать внешний браузер:
    http://fire-monkey.ru/topic/3236-открыть-ссылку/
  8. Like
    Камышев Александр получил реакцию от Олег Киреев в Почему не видны изменения в файле базы SQLite   
    Как все запущено... deploy означает разместить на мобильном устройстве, изменения будут в файле на телефоне или планшете.
    Посмотреть изменения можно или из программы, запросить 'select * from Tab_Parol', либо любой прогой из googleplay которая работает с sqlite.
    Хотя нет, internal сторонними программами не посмотришь, надо из своей контролить.
  9. Like
    Камышев Александр получил реакцию от Равиль Зарипов (ZuBy) в Почему не видны изменения в файле базы SQLite   
    Как все запущено... deploy означает разместить на мобильном устройстве, изменения будут в файле на телефоне или планшете.
    Посмотреть изменения можно или из программы, запросить 'select * from Tab_Parol', либо любой прогой из googleplay которая работает с sqlite.
    Хотя нет, internal сторонними программами не посмотришь, надо из своей контролить.
  10. Like
    Камышев Александр получил реакцию от Равиль Зарипов (ZuBy) в Почему не видны изменения в файле базы SQLite   
    Визуальные компоненты портят начинающих программеров...
    Query_Parol - это что? DBTable? Тексты запросов в студию.
    и транслитерация - плохой тон, почему бы не tbPassword?
  11. Like
    Камышев Александр получил реакцию от Alex7wrt в Как правильно организовать многопоточный алгоритм   
    имхо, с firemonkey неплохо работает такая схема:
    1. создать две потокозащищенные очереди (структуры), на си для этого подходит std::deque, в fmx можно TList. Защита стандартно TCriticalSection;
    2. создать несколько потоков, с помощью TEvent указать им ссылки на очереди и критические секции;
    3. в потоках:
     3.1 TCriticalSection::Enter лочим очередь задач,
     3.2 забираем крайнюю задачу
     3.3 TCriticalSection::Leave отпускаем очередь задач
     3.4 вычисления
     3.5 по аналогии с очередью задач лочим очередь результатов, выкладываем результаты, отпускаем
     3.6 повтор с пункта 3.1
    4. в основном потоке в очереди (тоже lock unlock) выкладывать задачи и при наличии результатов отрисовывать имеющимися средствами.
    в 4 пункте нужен будет нужен будет какой-нибудь mmtimer.
     
  12. Like
    Камышев Александр получил реакцию от Winexcel в DealLock или что сделать чтобы его получить   
    deadlock? - легко:
    TCriticalSection *cs = new TCriticalSection(); cs->Enter(); cs->Enter();
  13. Like
    Камышев Александр получил реакцию от enatechno в What's New in C++Builder 10.2   
    Unix то да, только до сих пор это были java приложения для виртуальной машины, теперь можно создавать исполняемые ELF файлы консольных приложений и библиотеки под unix.
     
    выше было видео, создание Apache dynamic link module, вот здесь c 45 минуты:
     
  14. Like
    Камышев Александр отреагировална chaplin.u@gmail.com в Многоязыковое приложение   
    как оказалось не все знали что установка   _TCHAR mapping to wchar_t"  должна заменять L. 
    Таки подстановка L решила проблему. вот и верь им после этого.
  15. Like
    Камышев Александр отреагировална chaplin.u@gmail.com в Многоязыковое приложение   
    конечно нет. поэтому я и вставил AnsiToUtf8 а "L" из другой оперы. меня тут просветили.
    кстати это лишнее т.к. "This conversion is automatically done for you when you set _TCHAR mapping to wchar_t". а это уже стоит в настройках студии.
  16. Like
    Камышев Александр получил реакцию от chaplin.u@gmail.com в Многоязыковое приложение   
    чем плох стандартный TLang? свойство
    AutoSelect=True - автоматическое определение языка и StoreInForm=True - хранить в ресурсах
    использую TLang для статичных строк и вот такой код для статусов и сообщений:
    String LangString( unsigned int code, AnsiString lang ) { if ( lang == "RU" ) switch( code ) { case 0: return (AnsiString)"Ожидание"; case 60: return (AnsiString)" не выполнено"; case 61: return (AnsiString)" выполнено успешно"; } else if ( lang == "EN" ) switch( code ) { case 0: return "Waiting"; case 60: return " not completed"; case 61: return " completed successfully"; } return "";  
  17. Like
    Камышев Александр получил реакцию от Rusland в Нет callback от TFDQuery   
    мдя, чудес не бывает, в базе и близко нет 3к записей в секунду, из-за ошибки с флагом наложение данных и до записи доходит процентов 10-20, потому и ресурсов мало потребляет.
  18. Like
    Камышев Александр получил реакцию от Rusland в Нет callback от TFDQuery   
    При запросе оборудование сообщает серверу свои параметры, сервер записывает их в базу, всего три записи в три таблицы, два целых числа и одна строка плюс ключевые поля. Selectы сервер делает периодически, через 5 минут, обновление кэша. Практически идет только запись. 
    На пакет http ответ уходит сразу, без подтверждения записи в бд. Если ждать подтверждение скорость резко падает, и больше 600-800 http запросов служба затыкается, краш где-то получается.
    Всего удалось получить больше 3000 тысяч запросов т.е. 3000 * 3 = 9к в секунду, движок СУБД при этом занимает 10-15% загрузки.
    MySql с максимальными настройками, измерял время потраченное на три запроса - поднималось в пике до 50мс. Десять коннектов держали по 300 таких пакетов запросов, т.е. среднее время должно было быть ~3 мс на запрос. Как-то не сходится... буду дальше копать
  19. Like
    Камышев Александр получил реакцию от Kitty в Быстродействие при использовании TCrititcalSection и TThread   
    думаю эти два куска показывают основную обработку OnCommandGet,
    из хедера:
    typedef std::deque< strDBQueueMember* > db_queue_deque; db_queue_deque db_queue; TCriticalSection *cs_pool, *cs_queue, *cs_files; TInterlocked *Interlocked; 3600 это запрос без обращения к бд, только данные из пула с критическими секциями 
    ну и вот это обязательно в System.Classes.pas  в Embarcadero\Studio\17.0\source\rtl\common\
    constructor TThread.Create(CreateSuspended: Boolean); -//- {$IF Defined(MSWINDOWS)} //#define STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000 - это для информации //#define CREATE_SUSPENDED 0x00000004 - это для информации // заменить FHandle := BeginThread(nil, 0, @ThreadProc, Pointer(Self), CREATE_SUSPENDED, FThreadID); // на FHandle := BeginThread(nil, 65536, @ThreadProc, Pointer(Self), $00010004, FThreadID); System.Classes.pas добавить в проект.
    и будет вам счастье 
  20. Like
    Камышев Александр получил реакцию от Евгений Корепов в Быстродействие при использовании TCrititcalSection и TThread   
    результаты краш-теста - упал в "Недостаточно памяти" после 5770 запросов в секунду, как бы и ничего так  
    С обращением к пулу - 3к и без задержек на доступ к критическим секциям 5к запросов с задержкой 200 мсек. - непринужденно, конечно после допила системного TThread, беда кстати была не в инди, а в теплом ламповом borland.
    тестировалось на ПК разработчика, сервер и эмулятор на localhost:

  21. Like
    Камышев Александр получил реакцию от Евгений Корепов в Быстродействие при использовании TCrititcalSection и TThread   
    Не думаю что сколько нибудь заметно, если брать http пакеты, ведь TIdHTTPServer наследник от TIdCustomTCPServer. Если пересылать бинарные массивы, без парсинга хедеров - возможно и будет небольшое увеличение.
    Был приятно удивлен, по всем ядрам ровная нагрузка.
  22. Like
    Камышев Александр получил реакцию от Rusland в Быстродействие при использовании TCrititcalSection и TThread   
    думаю эти два куска показывают основную обработку OnCommandGet,
    из хедера:
    typedef std::deque< strDBQueueMember* > db_queue_deque; db_queue_deque db_queue; TCriticalSection *cs_pool, *cs_queue, *cs_files; TInterlocked *Interlocked; 3600 это запрос без обращения к бд, только данные из пула с критическими секциями 
    ну и вот это обязательно в System.Classes.pas  в Embarcadero\Studio\17.0\source\rtl\common\
    constructor TThread.Create(CreateSuspended: Boolean); -//- {$IF Defined(MSWINDOWS)} //#define STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000 - это для информации //#define CREATE_SUSPENDED 0x00000004 - это для информации // заменить FHandle := BeginThread(nil, 0, @ThreadProc, Pointer(Self), CREATE_SUSPENDED, FThreadID); // на FHandle := BeginThread(nil, 65536, @ThreadProc, Pointer(Self), $00010004, FThreadID); System.Classes.pas добавить в проект.
    и будет вам счастье 
  23. Like
    Камышев Александр получил реакцию от Евгений Корепов в Быстродействие при использовании TCrititcalSection и TThread   
    думаю эти два куска показывают основную обработку OnCommandGet,
    из хедера:
    typedef std::deque< strDBQueueMember* > db_queue_deque; db_queue_deque db_queue; TCriticalSection *cs_pool, *cs_queue, *cs_files; TInterlocked *Interlocked; 3600 это запрос без обращения к бд, только данные из пула с критическими секциями 
    ну и вот это обязательно в System.Classes.pas  в Embarcadero\Studio\17.0\source\rtl\common\
    constructor TThread.Create(CreateSuspended: Boolean); -//- {$IF Defined(MSWINDOWS)} //#define STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000 - это для информации //#define CREATE_SUSPENDED 0x00000004 - это для информации // заменить FHandle := BeginThread(nil, 0, @ThreadProc, Pointer(Self), CREATE_SUSPENDED, FThreadID); // на FHandle := BeginThread(nil, 65536, @ThreadProc, Pointer(Self), $00010004, FThreadID); System.Classes.pas добавить в проект.
    и будет вам счастье 
  24. Like
    Камышев Александр получил реакцию от dnekrasov в Перспективы RAD   
    Менеджер отправился к Великому Программисту и показал ему техзадание для новой программы. Менеджер спросил Мастера: «Сколько времени займёт у вас разработка этой системы, если я назначу вам пять программистов?»
    «Один год» — быстро ответил Мастер.
    «Но нам она нужна вчера! Как долго вы будете её разрабатывать, если я вам дам десять программистов?»
    Мастер нахмурился, и сказал: «тогда два года».
    «А если я назначу вам сотню программистов?»
    Мастер пожал плечами: «В таком случае, она никогда не будет завершена» 
  25. Like
    Камышев Александр получил реакцию от Rusland в Быстродействие при использовании TCrititcalSection и TThread   
    Windows, FMX
    Возможно не совсем в тему форума, вопрос по архитектуре серверных служб, хотелось бы услышать мнения.
    Ситуация:
    IdHTTTPServer на каждый запрос создает поток, в этом потоке не обойтись без обращения к пулу данных в памяти. Пул - несколько наборов актуальных данных. Наборы данных асинхронно получаются из БД, имеют связи многие ко многим, один ко многим и периодически кэшируются в память в основном потоке. Т.к. обращение к пулу из потока - соответственно пул должен быть потокозащищенным. После обработки запроса, данные также отправляются в  основном потоке в очередь БД.
    1. Если весь пул закрыть в TCriticalSection - то на время использования его одним потоком все остальные будут ожидать. Обращение к очереди БД из потока получается также должно быть потокозащищенным. Не изящно.
    2. Можно задачу обработки положить в некую потокозащищенную очередь и остановить поток c помощью TSimpleEvent->WaitFor( INFINITE ). Далее в основном потоке работать с пулом данных и очередью БД без критических сессий и, после получения результата, запустить поток SetEvent(). Код будет проще и понятней, однако задачи будут выполняться синхронно, последовательно как и в первом случае.
    3. Можно закрывать TCriticalSection отдельные наборы данных, это возможно несколько увеличит быстродействие (не факт!), усложнит код и увеличит вероятность deadlock, т.к. для обработки одного запроса используется несколько наборов данных. Deadlock не будет, если перед обращением к следующему набору ( critical_section->Enter() ) копировать что необходимо из предыдущего и отпускать его ( critical_section->Leave() ) - тут становится важна стоимость операторов копирования.При больших объемах, стоимость копирования может перекрыть весь профит от частного обращения к наборам.
    TThread полезно использовать при длительных операциях ввода вывода и ресурсоемких операциях, т.е. когда нужно подождать, не останавливая основной поток. Выигрыша в производительности полагаю нет, к тому же переключения критических секций также имеют стоимость. 
    Вопросы:
    1. Какой вариант предпочтительней? Есть стандартные схемы?
    2. Как влияет количество ядер, процессоров, на быстродействие во втором и третьем случае?
×
×
  • Создать...