четверг, ноября 06, 2014

Пространства имен. Неработающая фича Delphi.

В процессе очередного рефакторинга обнаружилось, что пространства имен в Delphi, которые для нативных дельфей стали доступны еще в Delphi 2006, если не раньше, попросту не работают. Как именно они не работают я отписал в QC#128737. А также оформил небольшой фич-риквест QC#128740. Не сочтите за труд, поддержите голосованием.

воскресенье, апреля 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

среда, февраля 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-приложениях.

QC#122138

понедельник, января 20, 2014

Если хочешь быть здоров…

…закаляйся!

IMG_20140119_115636

IMG_20140119_115645

Уже пятый год, на Крещение, ходим с друзьями купаться. Вчера было здорово. Погода прекрасная: легкий морозец (-22 градуса) и едва заметный снежок.

понедельник, января 06, 2014

Delphi. Ненависть 2.

В посте Delphi. Ненависть. я показал как деградировал кодогенератор дельфей. Сегодня покажу еще раз, только уже с кодом на котором проблема воспроизводится.