/packages/fcl-res/src/resfactory.pp

https://github.com/slibre/freepascal · Puppet · 151 lines · 124 code · 27 blank · 0 comment · 9 complexity · da3dff34b3645efd86c10618097eb4ab MD5 · raw file

  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2008 by Giulio Bernardi
  4. Factory class for resources
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. unit resfactory;
  12. {$MODE OBJFPC}
  13. interface
  14. uses
  15. Classes, SysUtils, resource;
  16. type
  17. EResourceFactoryException = class(EResourceException);
  18. EResourceClassAlreadyRegisteredException = class(EResourceFactoryException);
  19. resourcestring
  20. SAlreadyRegistered = 'A resource class for the type %s is already registered.';
  21. type
  22. { TResourceFactory }
  23. TResourceFactory = class
  24. private
  25. class procedure InitResTypeList;
  26. class procedure DisposeResTypeList;
  27. class function FindResourceClass(aType : TResourceDesc) : TResourceClass;
  28. protected
  29. public
  30. class procedure RegisterResourceClass(aType : TResID; aClass : TResourceClass); overload;
  31. class procedure RegisterResourceClass(aType : TResName; aClass : TResourceClass); overload;
  32. class procedure RegisterResourceClass(aType : TResourceDesc; aClass : TResourceClass); overload;
  33. class function CreateResource(aType, aName : TResourceDesc) : TAbstractResource;
  34. end;
  35. implementation
  36. type
  37. TRegisteredResourceEntry = record
  38. _type : TResourceDesc;
  39. _class : TResourceClass;
  40. end;
  41. PRegisteredResourceEntry = ^TRegisteredResourceEntry;
  42. var
  43. ResTypeList : TFPList = nil;
  44. { TResourceFactory }
  45. class procedure TResourceFactory.InitResTypeList;
  46. begin
  47. if ResTypeList=nil then
  48. ResTypeList:=TFPList.Create;
  49. end;
  50. class procedure TResourceFactory.DisposeResTypeList;
  51. var i : integer;
  52. p : PRegisteredResourceEntry;
  53. begin
  54. if ResTypeList=nil then exit;
  55. for i:=0 to ResTypeList.Count-1 do
  56. begin
  57. p:=PRegisteredResourceEntry(ResTypeList[i]);
  58. p^._type.Free;
  59. FreeMem(p);
  60. end;
  61. FreeAndNil(ResTypeList);
  62. end;
  63. class function TResourceFactory.FindResourceClass(aType: TResourceDesc
  64. ): TResourceClass;
  65. var i : integer;
  66. p : PRegisteredResourceEntry;
  67. begin
  68. InitResTypeList;
  69. for i:=0 to ResTypeList.Count-1 do
  70. begin
  71. p:=PRegisteredResourceEntry(ResTypeList[i]);
  72. if p^._type.Equals(aType) then
  73. begin
  74. Result:=p^._class;
  75. exit;
  76. end;
  77. end;
  78. Result:=nil;
  79. end;
  80. class procedure TResourceFactory.RegisterResourceClass(aType : TResID;
  81. aClass : TResourceClass); overload;
  82. var t : TResourceDesc;
  83. begin
  84. t:=TResourceDesc.Create(aType);
  85. try
  86. RegisterResourceClass(t,aClass);
  87. finally
  88. t.Free;
  89. end;
  90. end;
  91. class procedure TResourceFactory.RegisterResourceClass(aType : TResName;
  92. aClass : TResourceClass); overload;
  93. var t : TResourceDesc;
  94. begin
  95. t:=TResourceDesc.Create(aType);
  96. try
  97. RegisterResourceClass(t,aClass);
  98. finally
  99. t.Free;
  100. end;
  101. end;
  102. class procedure TResourceFactory.RegisterResourceClass(aType: TResourceDesc;
  103. aClass: TResourceClass);
  104. var p : PRegisteredResourceEntry;
  105. begin
  106. if FindResourceClass(aType)<>nil then
  107. raise EResourceClassAlreadyRegisteredException.CreateFmt(SAlreadyRegistered,[aType.Name]);
  108. p:=GetMem(sizeof(TRegisteredResourceEntry));
  109. p^._type:=TResourceDesc.Create;
  110. p^._type.Assign(aType);
  111. p^._class:=aClass;
  112. ResTypeList.Add(p);
  113. end;
  114. class function TResourceFactory.CreateResource(aType, aName: TResourceDesc
  115. ): TAbstractResource;
  116. var theclass : TResourceClass;
  117. begin
  118. theclass:=FindResourceClass(aType);
  119. if theclass=nil then theclass:=TGenericResource;
  120. Result:=theclass.Create(aType,aName);
  121. end;
  122. finalization
  123. TResourceFactory.DisposeResTypeList;
  124. end.