четверг, ноября 06, 2014
Пространства имен. Неработающая фича Delphi.
воскресенье, апреля 13, 2014
Эмуляция перегружаемых дефолтных свойств во FreePascal 2.7.1
В настоящий момент FreePascal не поддерживает перегружаемые дефолтные свойства (на что есть соответствующий запрос), поддержка которых появилась в Delphi после седьмой версии. Нельзя сказать, что это киллер-фича, но иногда она бывает очень полезной. Однако, с появлением поддержки улучшенных записей (advanced records) и перегрузки операторов появилась возможность немного сгладить этот досадный недостаток. От слов к коду:
program project1;
{$IFNDEF FPC}
{$APPTYPE CONSOLE}
{$DEFINE HAS_OVERLOADABLE_DEFAULT_PROPERTIES}
{$ELSE}
{$MODE DELPHI}
{$ENDIF}
Type
//
TContainer = Record
{$IFNDEF HAS_OVERLOADABLE_DEFAULT_PROPERTIES}
Strict Private
Type
//
StringNameOrIntegerId = Record
FKind : (ikName, ikId);
FName : String;
FId : Integer;
Class Operator Implicit(Const AName : String) : StringNameOrIntegerId;
Class Operator Implicit(Const AId : Integer) : StringNameOrIntegerId;
End;
//
{$ENDIF}
Private
Function GetItemByName(Const AName : String) : TObject;
Function GetItemById(Const AId : Integer) : TObject;
{$IFNDEF HAS_OVERLOADABLE_DEFAULT_PROPERTIES}
Function GetItem(Const ANameOrId : StringNameOrIntegerId) : TObject;
{$ENDIF}
Public
{$IFDEF HAS_OVERLOADABLE_DEFAULT_PROPERTIES}
Property Items[Const AName : String] : TObject Read GetItemByName; Default;
Property Items[Const AId : Integer] : TObject Read GetItemById; Default;
{$ELSE}
Property Items[Const ANameOrId : StringNameOrIntegerId] : TObject Read GetItem; Default;
{$ENDIF}
End;
{$IFNDEF HAS_OVERLOADABLE_DEFAULT_PROPERTIES}
{ TContainer.StringNameOrIntegerId }
//
Class Operator TContainer.StringNameOrIntegerId.Implicit(Const AName : String) : StringNameOrIntegerId;
Begin
Result.FKind := ikName;
Result.FName := AName;
End;
//
//
Class Operator TContainer.StringNameOrIntegerId.Implicit(Const AId : Integer) : StringNameOrIntegerId;
Begin
Result.FKind := ikId;
Result.FId := AId;
End;
//
{$ENDIF}
{ TContainer }
//
Function TContainer.GetItemByName(Const AName : String) : TObject;
Begin
Result := TObject(1); // stub
End;
//
//
Function TContainer.GetItemById(Const AId : Integer) : TObject;
Begin
Result := TObject(2); // stub
End;
//
{$IFNDEF HAS_OVERLOADABLE_DEFAULT_PROPERTIES}
//
Function TContainer.GetItem(Const ANameOrId : StringNameOrIntegerId) : TObject;
Begin
Case ANameOrId.FKind Of
ikName : Result := GetItemByName(ANameOrId.FName);
ikId : Result := GetItemById(ANameOrId.FId);
End;
End;
//
{$ENDIF}
Var
cnt : TContainer;
begin
Assert(cnt['name'] = TObject(1));
Assert(cnt[1024] = TObject(2));
WriteLn('Overloadable default properties works fine!');
ReadLn;
end.
Это готовый пример который можно собрать в Delphi и FreePascal 2.7.1. Из кода видно, что проблему решает новый тип – улучшеная запись выступающий в качестве типа индекса дефолтного свойства и инкапсулирующий реальный тип индекса. Прикладной код, при этом, остается полностью совместимым с Delphi и возможной поддержкой перегружаемых дефолтных свойств во FreePascal в будущем.
Данный метод также может пригодится в случае, когда некое свойство (не обязательно перегружаемое и дефолтное) должно принимать значения ограниченного числа типов, т.е. это может быть полезно не только для FreePascal, но и для Delphi.
четверг, марта 20, 2014
QPS в действии?
18 марта, баг-репорт QC#121566, которому были посвящены четыре поста “с ассемблером”, получил статус Resolved. Это, конечно, еще не Closed, но... Будем надеяться :) Хотя сам по себе факт решения проблемы довольно будничный, но не упомянуть о нем после широкой огласки было-бы несправедливо. Хочу поблагодарить всех, кто проголосовал, а также тех, кто способствовал распространению информации о данной проблеме. Спасибо.
Напомню, что в обновленной дорожной карте RAD Studio, Delphi and C++Builder на 2014 год, одним из пунктов декларируется QPS (Quality, Performance, Stability). Давно пора!
вторник, марта 11, 2014
Delphi. Ненависть. Продолжение истории.
В попытках найти решение проблемы с говнокодогенератором Delphi, я понял, что все хуже, чем я предполагал.
среда, февраля 05, 2014
Delphi. Ненависть 2. 64-битная версия
Пост-продолжение Delphi. Ненависть 2.
------------------------------ Delphi XE2 Update 4 Hotfix 1 x64:
Project1.dpr.68: Utils.Namespace.CompareString(S1, S2);
0000000000426680 488D4D58 lea rcx,[rbp+$58]
0000000000426684 488B15BDEB0000 mov rdx,[rel $0000ebbd]
000000000042668B E86020FEFF call @UStrLAsg
0000000000426690 488D4D50 lea rcx,[rbp+$50]
0000000000426694 488B15B5EB0000 mov rdx,[rel $0000ebb5]
000000000042669B E85020FEFF call @UStrLAsg
00000000004266A0 488B4D58 mov rcx,[rbp+$58]
00000000004266A4 488B5550 mov rdx,[rbp+$50]
00000000004266A8 E82349FFFF call CompareStr
Project1.dpr.69: Utils.Namespace.SameString(S1, S2);
00000000004266AD 488D4D48 lea rcx,[rbp+$48]
00000000004266B1 488B1590EB0000 mov rdx,[rel $0000eb90]
00000000004266B8 E83320FEFF call @UStrLAsg
00000000004266BD 488D4D40 lea rcx,[rbp+$40]
00000000004266C1 488B1588EB0000 mov rdx,[rel $0000eb88]
00000000004266C8 E82320FEFF call @UStrLAsg
00000000004266CD 488D4D38 lea rcx,[rbp+$38]
00000000004266D1 488B5548 mov rdx,[rbp+$48]
00000000004266D5 E81620FEFF call @UStrLAsg
00000000004266DA 488D4D30 lea rcx,[rbp+$30]
00000000004266DE 488B5540 mov rdx,[rbp+$40]
00000000004266E2 E80920FEFF call @UStrLAsg
00000000004266E7 488B4D38 mov rcx,[rbp+$38]
00000000004266EB 488B5530 mov rdx,[rbp+$30]
00000000004266EF E8DC48FFFF call CompareStr
------------------------------ Delphi XE5 Update 2 x64:
Project1.dpr.68: Utils.Namespace.CompareString(S1, S2);
0000000000426F94 488D4D78 lea rcx,[rbp+$78]
0000000000426F98 488B1581F20000 mov rdx,[rel $0000f281]
0000000000426F9F E88C23FEFF call @UStrLAsg
0000000000426FA4 488D4D70 lea rcx,[rbp+$70]
0000000000426FA8 488B1579F20000 mov rdx,[rel $0000f279]
0000000000426FAF E87C23FEFF call @UStrLAsg
0000000000426FB4 90 nop
0000000000426FB5 488B4D78 mov rcx,[rbp+$78]
0000000000426FB9 488B5570 mov rdx,[rbp+$70]
0000000000426FBD E86E34FFFF call CompareStr
0000000000426FC2 89453C mov [rbp+$3c],eax
0000000000426FC5 90 nop
0000000000426FC6 488D4D78 lea rcx,[rbp+$78]
0000000000426FCA E8411EFEFF call @UStrClr
0000000000426FCF 488D4D70 lea rcx,[rbp+$70]
0000000000426FD3 E8381EFEFF call @UStrClr
Project1.dpr.69: Utils.Namespace.SameString(S1, S2);
0000000000426FD8 488D4D58 lea rcx,[rbp+$58]
0000000000426FDC 488B153DF20000 mov rdx,[rel $0000f23d]
0000000000426FE3 E84823FEFF call @UStrLAsg
0000000000426FE8 488D4D50 lea rcx,[rbp+$50]
0000000000426FEC 488B1535F20000 mov rdx,[rel $0000f235]
0000000000426FF3 E83823FEFF call @UStrLAsg
0000000000426FF8 488D4D68 lea rcx,[rbp+$68]
0000000000426FFC E80F1EFEFF call @UStrClr
0000000000427001 488D4D60 lea rcx,[rbp+$60]
0000000000427005 E8061EFEFF call @UStrClr
000000000042700A 488D4D48 lea rcx,[rbp+$48]
000000000042700E E8FD1DFEFF call @UStrClr
0000000000427013 488D4D40 lea rcx,[rbp+$40]
0000000000427017 E8F41DFEFF call @UStrClr
000000000042701C 90 nop
000000000042701D 488D4D68 lea rcx,[rbp+$68]
0000000000427021 488B5558 mov rdx,[rbp+$58]
0000000000427025 E80623FEFF call @UStrLAsg
000000000042702A 488D4D60 lea rcx,[rbp+$60]
000000000042702E 488B5550 mov rdx,[rbp+$50]
0000000000427032 E8F922FEFF call @UStrLAsg
0000000000427037 90 nop
0000000000427038 488B4D68 mov rcx,[rbp+$68]
000000000042703C 488B5560 mov rdx,[rbp+$60]
0000000000427040 E8EB33FFFF call CompareStr
0000000000427045 894534 mov [rbp+$34],eax
0000000000427048 90 nop
0000000000427049 488D4D68 lea rcx,[rbp+$68]
000000000042704D E8BE1DFEFF call @UStrClr
0000000000427052 488D4D60 lea rcx,[rbp+$60]
0000000000427056 E8B51DFEFF call @UStrClr
000000000042705B 837D3400 cmp dword ptr [rbp+$34],$00
000000000042705F 0F94C0 setz al
0000000000427062 88453B mov [rbp+$3b],al
0000000000427065 90 nop
0000000000427066 488D4D58 lea rcx,[rbp+$58]
000000000042706A E8A11DFEFF call @UStrClr
000000000042706F 488D4D50 lea rcx,[rbp+$50]
0000000000427073 E8981DFEFF call @UStrClr
0000000000427078 488D4D68 lea rcx,[rbp+$68]
000000000042707C E88F1DFEFF call @UStrClr
0000000000427081 488D4D60 lea rcx,[rbp+$60]
0000000000427085 E8861DFEFF call @UStrClr
000000000042708A 488D4D48 lea rcx,[rbp+$48]
000000000042708E E87D1DFEFF call @UStrClr
0000000000427093 488D4D40 lea rcx,[rbp+$40]
0000000000427097 E8741DFEFF call @UStrClr
------------------------------ FreePascal 2.7.1. x64:
project1.lpr:68 Utils.Namespace.CompareString(S1, S2);
000000010000158A 488b157fda0100 mov 0x1da7f(%rip),%rdx # 0x10001f010
0000000100001591 488b0d68da0100 mov 0x1da68(%rip),%rcx # 0x10001f000
0000000100001598 e843e40000 callq 0x10000f9e0 <SYSUTILS_$$_COMPARESTR$ANSISTRING$ANSISTRING$$LONGINT>
project1.lpr:69 Utils.Namespace.SameString(S1, S2);
000000010000159D 488b156cda0100 mov 0x1da6c(%rip),%rdx # 0x10001f010
00000001000015A4 488b0d55da0100 mov 0x1da55(%rip),%rcx # 0x10001f000
00000001000015AB e830e40000 callq 0x10000f9e0 <SYSUTILS_$$_COMPARESTR$ANSISTRING$ANSISTRING$$LONGINT>
00000001000015B0 85c0 test %eax,%eax
00000001000015B2 0f94c0 sete %al
пятница, января 31, 2014
Firemonkey, которая гуляет сама по себе.
В одном из прошлых постов я упоминал о фантомных срабатываниях сенсорного экрана в Firemonkey-приложениях. Ввиду того, что воспроизвести это не так просто, а на слово верить в такое не хочется, пару дней назад я заснял этот эффект на видео. Прошу прощения за качество, делалось впопыхах.
Воспроизведено на устройстве Huawei Ascend Mate, Android 4.1.2, ланчер EmotionUI 1.5.
Проект на котором очень хорошо воспроизводятся эти эффекты можно взять тут (прямая ссылка).
На видео видно, что несмотря на фантомные срабатывания, когда к устройству даже не прикосаешься, само приложение никак не реагирует на прикосновения пальца (это бывает не всегда, и иногда оно таки реагирует). Более того, перестают реагировать даже системные навигационные кнопки. Все это безобразие можно прекратить только нажатием аппаратной кнопки выключения.
Нужно заметить, что ни в одном другом приложении, ни основанных на SDK, ни на NDK таких эффектов не наблюдается. К телефону вообще нет ни малейших претензий. Воспроизводится это только в Firemonkey-приложениях.
понедельник, января 20, 2014
Если хочешь быть здоров…
…закаляйся!
Уже пятый год, на Крещение, ходим с друзьями купаться. Вчера было здорово. Погода прекрасная: легкий морозец (-22 градуса) и едва заметный снежок.
понедельник, января 06, 2014
Delphi. Ненависть 2.
В посте Delphi. Ненависть. я показал как деградировал кодогенератор дельфей. Сегодня покажу еще раз, только уже с кодом на котором проблема воспроизводится.