View Issue Details

IDProjectCategoryView StatusLast Update
0003728JEDI VCL00 JVCL Componentspublic2006-06-08 03:44
ReporterKiriakosAssigned Toobones 
PrioritynormalSeverityfeatureReproducibilityalways
Status resolvedResolutionfixed 
Product Version3.20 
Target VersionFixed in Version3.30 
Summary0003728: JvAppStrorage could avoid saving properties with default values
DescriptionJvAppStrorage could avoid saving properties with default values as Delphi does when it saves forms. This could save space and loading/saving time.
TagsNo tags attached.

Activities

obones

2006-06-05 01:48

administrator   ~0009377

How do you get the default value for a property ?

2006-06-05 05:00

 

JvAppStoragepatch.txt (2,586 bytes)
diff w C:\TEMP\JvAppStorage.pas C:\Sandbox\P4D\PythonForDelphi\PythonIDE\JvAppStorage.pas
669a670
>     FStoreDefaultValues : Boolean;
681a683
>     procedure SetStoreDefaultValues(const Value: Boolean);
702a705,706
>     property StoreDefaultValues : Boolean read FStoreDefaultValues
>       write SetStoreDefaultValues default False;
716a721
>     property StoreDefaultValues;
1128a1134,1139
> procedure TJvCustomAppStorageOptions.SetStoreDefaultValues(
>   const Value: Boolean);
> begin
>   FStoreDefaultValues := Value;
> end;
> 
2461a2473,2507
> 
>   function IsDefaultOrdProp(PropInfo: PPropInfo): Boolean;
>   var
>     Value: Longint;
>     Default: LongInt;
>   begin
>     Value := GetOrdProp(PersObj, PropInfo);
>     Default := PPropInfo(PropInfo)^.Default;
>     Result :=  (Default <> LongInt($80000000)) and (Value = Default);
>   end;
> 
>   function IsDefaultStrProp(PropInfo: PPropInfo): Boolean;
>   var
>     Value: WideString;
>   begin
>     Value := GetWideStrProp(PersObj, PropInfo);
>     Result := Value = '';
>   end;
> 
>   function IsDefaultInt64Prop(PropInfo: PPropInfo): Boolean;
>   var
>     Value: Int64;
>   begin
>     Value := GetInt64Prop(PersObj, PropInfo);
>     Result := Value = 0;
>   end;
> 
>   function IsDefaultFloatProp(PropInfo: PPropInfo): Boolean;
>   var
>     Value: Extended;
>   begin
>     Value := GetFloatProp(PersObj, PropInfo);
>     Result := Value = 0;
>   end;
> 
2470a2517,2519
>       begin
>         P := GetPropInfo(PersObj, PropName, tkAny);
>         if StorageOptions.StoreDefaultValues or not IsDefaultStrProp(P) then
2471a2521
>       end;
2473a2524,2526
>         P := GetPropInfo(PersObj, PropName, tkAny);
>         if StorageOptions.StoreDefaultValues or not IsDefaultOrdProp(P) then
>         begin
2476a2530
>       end;
2478a2533,2535
>         P := GetPropInfo(PersObj, PropName, tkAny);
>         if StorageOptions.StoreDefaultValues or not IsDefaultOrdProp(P) then
>         begin
2481a2539
>       end;
2483a2542,2544
>         P := GetPropInfo(PersObj, PropName, tkAny);
>         if StorageOptions.StoreDefaultValues or not IsDefaultOrdProp(P) then
>         begin
2491a2553
>       end;
2492a2555,2557
>       begin
>         P := GetPropInfo(PersObj, PropName, tkAny);
>         if StorageOptions.StoreDefaultValues or not IsDefaultInt64Prop(P) then
2493a2559
>       end;
2496a2563,2564
>         if StorageOptions.StoreDefaultValues or not IsDefaultFloatProp(P) then
>         begin
2500a2569
>         end;
JvAppStoragepatch.txt (2,586 bytes)

Kiriakos

2006-06-05 05:01

reporter   ~0009380

See the attached file for an implementation of this feature and the answer to your question. It is a diff file against the current SVN version of JvAppStorage.pas

obones

2006-06-05 08:01

administrator   ~0009385

Nice patch here.
I have some question:
Why is the default value for Int64 forced to be 0? Delphi's compiler accepts a Int64 property with a default value, isn't there a way to retrieve it?
Is there a way to retrieve the value returned by a "stored" property marker? You know, the value returned by the function given just after the "stored" keyword.

I tested the Int64 part with Delphi 7 and 2006.
Thanks a lot for the patch, it's good to go, just curious about the two points above.

2006-06-05 15:35

 

JvAppStoragepatch2.txt (3,276 bytes)
diff w C:\TEMP\JvAppStorage.pas C:\Sandbox\P4D\PythonForDelphi\PythonIDE\JvAppStorage.pas
669a670
>     FStoreDefaultValues : Boolean;
681a683
>     procedure SetStoreDefaultValues(const Value: Boolean);
702a705,706
>     property StoreDefaultValues : Boolean read FStoreDefaultValues
>       write SetStoreDefaultValues default False;
716a721
>     property StoreDefaultValues;
1128a1134,1139
> procedure TJvCustomAppStorageOptions.SetStoreDefaultValues(
>   const Value: Boolean);
> begin
>   FStoreDefaultValues := Value;
> end;
> 
2461a2473,2507
> 
>   function IsDefaultOrdProp(PropInfo: PPropInfo): Boolean;
>   var
>     Value: Longint;
>     Default: LongInt;
>   begin
>     Value := GetOrdProp(PersObj, PropInfo);
>     Default := PPropInfo(PropInfo)^.Default;
>     Result :=  (Default <> LongInt($80000000)) and (Value = Default);
>   end;
> 
>   function IsDefaultStrProp(PropInfo: PPropInfo): Boolean;
>   var
>     Value: WideString;
>   begin
>     Value := GetWideStrProp(PersObj, PropInfo);
>     Result := Value = '';
>   end;
> 
>   function IsDefaultInt64Prop(PropInfo: PPropInfo): Boolean;
>   var
>     Value: Int64;
>   begin
>     Value := GetInt64Prop(PersObj, PropInfo);
>     Result := Value = 0;
>   end;
> 
>   function IsDefaultFloatProp(PropInfo: PPropInfo): Boolean;
>   var
>     Value: Extended;
>   begin
>     Value := GetFloatProp(PersObj, PropInfo);
>     Result := Value = 0;
>   end;
> 
2468a2515,2522
> 
>   P := GetPropInfo(PersObj, PropName, tkAny);
> 
>   // Do not store read-only or write-only properties or properties that for which
>   // IsStoredProp returns false (as VCL does)
>   if (P^.GetProc = nil) or (P^.SetProc = nil) or not IsStoredProp(PersObj, P) then
>     Exit;
> 
2470a2525,2526
>       begin
>         if StorageOptions.StoreDefaultValues or not IsDefaultStrProp(P) then
2471a2528
>       end;
2473a2531,2532
>         if StorageOptions.StoreDefaultValues or not IsDefaultOrdProp(P) then
>         begin
2475c2534,2535
<         WriteEnumeration(Path, GetPropInfo(PersObj, PropName).PropType{$IFNDEF CLR}^{$ENDIF}, TmpValue);
---
>           WriteEnumeration(Path, P.PropType{$IFNDEF CLR}^{$ENDIF}, TmpValue);
>         end;
2478a2539,2540
>         if StorageOptions.StoreDefaultValues or not IsDefaultOrdProp(P) then
>         begin
2480c2542,2543
<         WriteSet(Path, GetPropInfo(PersObj, PropName).PropType{$IFNDEF CLR}^{$ENDIF}, TmpValue);
---
>           WriteSet(Path, P.PropType{$IFNDEF CLR}^{$ENDIF}, TmpValue);
>         end;
2483a2547,2548
>         if StorageOptions.StoreDefaultValues or not IsDefaultOrdProp(P) then
>         begin
2487c2552
<           WriteEnumeration(Path, GetPropInfo(PersObj, PropName).PropType{$IFNDEF CLR}^{$ENDIF}, TmpValue);
---
>             WriteEnumeration(Path, P.PropType{$IFNDEF CLR}^{$ENDIF}, TmpValue);
2491a2557
>       end;
2492a2559,2560
>       begin
>         if StorageOptions.StoreDefaultValues or not IsDefaultInt64Prop(P) then
2493a2562
>       end;
2496c2565,2566
<         P := GetPropInfo(PersObj, PropName, tkAny);
---
>         if StorageOptions.StoreDefaultValues or not IsDefaultFloatProp(P) then
>         begin
2500a2571
>         end;
JvAppStoragepatch2.txt (3,276 bytes)

Kiriakos

2006-06-05 15:43

reporter   ~0009389

New patch replacing old one uploaded.
Improvements:
- Do not store read-only or write-only properties
- Do not store properties for which IsStoredProp returns false
The above mimic standard VCL behaviour

Regarding Int64 properties, I am not sure Delphi respects a default value different than 0 (which should be considered a bug). Look at the code of IsDefaultPropertyValue in Classes.pas to see for yourself. If it does I am not able to see how.

Kiriakos

2006-06-05 15:44

reporter   ~0009390

New patch replacing old one uploaded.
Improvements:
- Do not store read-only or write-only properties
- Do not store properties for which IsStoredProp returns false
The above mimic standard VCL behaviour

Regarding Int64 properties, I am not sure Delphi respects a default value different than 0 (which should be considered a bug). Look at the code of IsDefaultPropertyValue in Classes.pas to see for yourself. If it does I am not able to see how.

jfudickar

2006-06-06 02:24

developer   ~0009391

My comment: I like the idea, but this should be an optional parameter and the default should be "saving the default values".

obones

2006-06-07 03:07

administrator   ~0009400

This is an optional parameter, so that is Fine.
However, I have one question: Why not simply call IsDefaultPropertyValue?
Something like that:

if not StorageOptions.StoreDefaultValues and
   (not Assigned(P^.GetProc) or not Assigned(P^.SetProc) or
    not IsStoredProp(PersObj, P) or IsDefaultPropertyValue(PersObj, P, nil)) then
  Exit;

I know this makes the new property also apply to Read/Write only properties and "stored" keyword, but that looks easier to me.

Kiriakos

2006-06-07 13:38

reporter   ~0009411

This was my original thought. However IsDefaultPropertyValue has features specific to storing components in VCL. For example it does not not store child component properties unless they are marked as SubComponents. See below:

Result := True;
  if (PropInfo^.GetProc <> nil) and
     ((PropInfo^.SetProc <> nil) or
     ((PropInfo^.PropType^.Kind = tkClass) and
      (TObject(GetOrdProp(Instance, PropInfo)) is TComponent) and
      (csSubComponent in TComponent(GetOrdProp(Instance, PropInfo)).ComponentStyle))) then

obones

2006-06-08 01:21

administrator   ~0009413

Well, not exactly. The second part is an "or", hence it will test for anything, even tkClass, when there is a setter.
Anyway, just to be on the safe side, I removed it from the initial condition and added it to every element of the case except tkClass.
This is now in SVN, let me know if that's ok with you so that I can close this issue.

jfudickar

2006-06-08 03:32

developer   ~0009441

Hi Olivier,

i've looked at your changes.

For backward compatibility, the default value of the property should be true.

Or we decide to ignore the backward compatibility.

Greetings
Jens

obones

2006-06-08 03:35

administrator   ~0009443

Yes, you are right, I changed this.

Kiriakos

2006-06-08 03:37

reporter   ~0009444

The changes are fine.

obones

2006-06-08 03:44

administrator   ~0009448

This is then marked as fixed. Thanks to everyone involved here.

Issue History

Date Modified Username Field Change
2006-05-26 02:20 Kiriakos New Issue
2006-06-05 01:48 obones Note Added: 0009377
2006-06-05 01:48 obones Status new => feedback
2006-06-05 05:00 Kiriakos File Added: JvAppStoragepatch.txt
2006-06-05 05:01 Kiriakos Note Added: 0009380
2006-06-05 08:01 obones Note Added: 0009385
2006-06-05 15:35 Kiriakos File Added: JvAppStoragepatch2.txt
2006-06-05 15:43 Kiriakos Note Added: 0009389
2006-06-05 15:44 Kiriakos Note Added: 0009390
2006-06-06 02:24 jfudickar Note Added: 0009391
2006-06-07 03:07 obones Note Added: 0009400
2006-06-07 13:38 Kiriakos Note Added: 0009411
2006-06-08 01:21 obones Note Added: 0009413
2006-06-08 03:32 jfudickar Note Added: 0009441
2006-06-08 03:35 obones Note Added: 0009443
2006-06-08 03:37 Kiriakos Note Added: 0009444
2006-06-08 03:44 obones Status feedback => resolved
2006-06-08 03:44 obones Resolution open => fixed
2006-06-08 03:44 obones Assigned To => obones
2006-06-08 03:44 obones Note Added: 0009448