├── .gitattributes ├── .github ├── FUNDING.yml ├── dependabot.yml └── workflows │ └── build.yml ├── .gitignore ├── 010_hello_world ├── Project1.dpr └── Project1.dproj ├── 020_fibonacci_naive ├── functions_etc.dpr └── functions_etc.dproj ├── 030_fibonacci_optimized ├── fibonacci_optimized.dpr └── fibonacci_optimized.dproj ├── 040_fibonacci_large ├── fibonacci_large.dpr └── fibonacci_large.dproj ├── 045_scoped_enums ├── scoped_enums.dpr └── scoped_enums.dproj ├── 050_sample_game ├── Project1.dpr └── Project1.dproj ├── 060_classes_basics ├── classes_basics.dpr └── classes_basics.dproj ├── 065_dangling_pointers_and_copying_refs ├── Project1.dpr └── Project1.dproj ├── 070_classes_ancestors ├── classes_ancestors.dpr └── classes_ancestors.dproj ├── 080_classes_freeing ├── classes_freeing.dpr └── classes_freeing.dproj ├── 090_classes_freeing_lists ├── 80_classes_freeing_lists.dpr └── 80_classes_freeing_lists.dproj ├── 100_classes_freeing_component ├── classes_freeing_component.dpr └── classes_freeing_component.dproj ├── 110_game_classes ├── game_classes.dpr └── game_classes.dproj ├── 120_simple_properties_example ├── simple_properties_example.dpr └── simple_properties_example.dproj ├── 125_properties_setter_limits └── properties_setter_limits.dpr ├── 130_array_properties ├── array_properties.dpr └── array_properties.dproj ├── 135_modules_include_files ├── UnitCreature.pas ├── UnitCreatureChild.pas ├── modules_include_files.dpr ├── modules_include_files.dproj └── myxxx.inc ├── 140_forms_etc ├── UnitDM.dfm ├── UnitDM.pas ├── UnitFormAutoCreated.fmx ├── UnitFormAutoCreated.pas ├── UnitFormNotAutoCreated.fmx ├── UnitFormNotAutoCreated.pas ├── UnitFormNotAutoCreatedDescendant.fmx ├── UnitFormNotAutoCreatedDescendant.pas ├── UnitFormUsingFrames.fmx ├── UnitFormUsingFrames.pas ├── UnitFrame.fmx ├── UnitFrame.pas ├── UnitFrameUsingFrames.fmx ├── UnitFrameUsingFrames.pas ├── forms_etc.dpr ├── forms_etc.dproj └── forms_etc.res ├── 150_data_module_using_components ├── Project1.dpr ├── Project1.dproj ├── Project1.res ├── UnitDataModule1.dfm ├── UnitDataModule1.pas └── component │ ├── Creature.pas │ ├── my_creature_package.dpk │ └── my_creature_package.dproj ├── 200_exceptions ├── exceptions.dpr └── exceptions.dproj ├── 205_DELIBERATELY_INCORRECT_freeing_memory_garbage └── memory_garbage_free.dpr ├── 210_exceptions_reraise ├── reraise.dpr └── reraise.dproj ├── 220_exceptions_finally ├── exceptions_finally.dpr └── exceptions_finally.dproj ├── 225_raise_in_constructor ├── raise_in_constructor.dpr └── raise_in_constructor.dproj ├── 230_classes_inside ├── classes_inside.dpr └── classes_inside.dproj ├── 235_class_helpers ├── class_helpers.dpr ├── class_helpers.dproj └── mycreatures.pas ├── 240_weak_ref ├── weak_ref.dpr └── weak_ref.dproj ├── 250_DELIBERATELY_INCORRECT_weak_ref_trap ├── weak_ref_trap.dpr └── weak_ref_trap.dproj ├── 260_class_methods_etc ├── class_methods_etc.dpr └── class_methods_etc.dproj ├── 270_class_refs ├── class_refs.dpr └── class_refs.dproj ├── 280_generics_simple ├── MyStringList.pas ├── generics_simple.dpr └── generics_simple.dproj ├── 285_generic_vectors └── generic_vectors.dpr ├── 287_generic_lists_usage └── generic_lists.dpr ├── 290_generics_2d_grid ├── MyGrid2D.pas ├── generics_2d_grid.dpr └── generics_2d_grid.dproj ├── 300_callbacks_events ├── callbacks_events.dpr └── callbacks_events.dproj ├── 305_callbacks_assigning └── func_callbacks.dpr ├── 310_anonymous ├── anonymous.dpr └── anonymous.dproj ├── 400_advanced_records_initialize ├── adv_rec.dpr └── adv_rec.dproj ├── LICENSE ├── Makefile ├── README.md └── github_orgazation_metadata ├── modern_pascal_organization_icon.png └── modern_pascal_organization_icon.xcf /.gitattributes: -------------------------------------------------------------------------------- 1 | # See https://github.com/github/linguist about the linguist attributes. 2 | 3 | # convert line endings, Pascal 4 | *.inc linguist-language=Pascal text eol=auto 5 | *.lpr linguist-language=Pascal text eol=auto 6 | *.dpr linguist-language=Pascal text eol=auto 7 | *.pas linguist-language=Pascal text eol=auto 8 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [castle-engine, michaliskambi] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: castleengine # Replace with a single Patreon username 5 | open_collective: castle-engine # Replace with a single Open Collective username 6 | # ko_fi: # Replace with a single Ko-fi username 7 | # tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | # community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | # liberapay: # Replace with a single Liberapay username 10 | # issuehunt: # Replace with a single IssueHunt username 11 | # otechie: # Replace with a single Otechie username 12 | # custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # Check that GitHub Actions use latest versions of plugins. 2 | # See https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot . 3 | 4 | version: 2 5 | updates: 6 | # Maintain dependencies for GitHub Actions 7 | - package-ecosystem: "github-actions" 8 | directory: "/" 9 | schedule: 10 | interval: "weekly" 11 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | # ---------------------------------------------------------------------------- 2 | # GitHub Actions workflow to test building all code samples. 3 | # 4 | # See docs: 5 | # - https://castle-engine.io/github_actions 6 | # - https://docs.github.com/en/actions 7 | # ---------------------------------------------------------------------------- 8 | 9 | name: Build All 10 | 11 | on: [push, pull_request] 12 | 13 | jobs: 14 | test-fpc: 15 | name: FPC stable 16 | runs-on: ubuntu-latest 17 | container: kambi/castle-engine-cloud-builds-tools:cge-none 18 | steps: 19 | - uses: actions/checkout@v4 20 | - run: make all 21 | 22 | test-fpc331: 23 | name: FPC 3.3.1 24 | runs-on: ubuntu-latest 25 | container: kambi/castle-engine-cloud-builds-tools:cge-none-fpc331 26 | steps: 27 | - uses: actions/checkout@v4 28 | - run: make all-fpc331 29 | 30 | delphi_test: 31 | name: Delphi 32 | strategy: 33 | matrix: 34 | host-label: [ 35 | delphi_12 36 | ] 37 | runs-on: ${{ matrix.host-label }} 38 | steps: 39 | - uses: actions/checkout@v4 40 | - name: Delphi Build (Win32) 41 | run: make all-delphi-win32 42 | - name: Delphi Build (Win64) 43 | run: make all-delphi-win64 44 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # artifacts by Delphi 2 | __history/ 3 | __recovery/ 4 | Win32/ 5 | Win64/ 6 | *.local 7 | *.identcache 8 | *.res 9 | *.rsm 10 | 11 | # artifacts by FPC 12 | *.o 13 | *.ppu 14 | 15 | # artifacts by any compiler 16 | *.exe 17 | # Unix binaries 18 | 010_hello_world/Project1 19 | 020_fibonacci_naive/functions_etc 20 | 030_fibonacci_optimized/fibonacci_optimized 21 | 040_fibonacci_large/fibonacci_large 22 | 045_scoped_enums/scoped_enums 23 | 060_classes_basics/classes_basics 24 | 065_dangling_pointers_and_copying_refs/Project1 25 | 070_classes_ancestors/classes_ancestors 26 | 080_classes_freeing/classes_freeing 27 | 090_classes_freeing_lists/80_classes_freeing_lists 28 | 100_classes_freeing_component/classes_freeing_component 29 | 110_game_classes/game_classes 30 | 120_simple_properties_example/simple_properties_example 31 | 125_properties_setter_limits/properties_setter_limits 32 | 130_array_properties/array_properties 33 | 135_modules_include_files/array_properties 34 | 205_DELIBERATELY_INCORRECT_freeing_memory_garbage/memory_garbage_free 35 | 225_raise_in_constructor/raise_in_constructor 36 | 270_class_refs/class_refs 37 | 280_generics_simple/generics_simple 38 | 285_generic_vectors/generic_vectors 39 | 287_generic_lists_usage/generic_lists 40 | 050_sample_game/Project1 41 | 200_exceptions/exceptions 42 | 210_exceptions_reraise/reraise 43 | 220_exceptions_finally/exceptions_finally 44 | 230_classes_inside/classes_inside 45 | 235_class_helpers/class_helpers 46 | 240_weak_ref/weak_ref 47 | 250_DELIBERATELY_INCORRECT_weak_ref_trap/weak_ref_trap 48 | 260_class_methods_etc/class_methods_etc 49 | 290_generics_2d_grid/generics_2d_grid 50 | 310_anonymous/anonymous 51 | 300_callbacks_events/callbacks_events 52 | 305_callbacks_assigning/func_callbacks 53 | 400_advanced_records_initialize/adv_rec 54 | -------------------------------------------------------------------------------- /010_hello_world/Project1.dpr: -------------------------------------------------------------------------------- 1 | { Simplest console application, the basis for our fun in this course. 2 | 3 | We deliberately start with console applications (though we will 4 | look at GUI applications later too, see "140_forms_etc") because 5 | it makes things easy to understand: we start with a clean slate, 6 | you don't need to understand concepts we will learn later (like classes) 7 | to understand how this program works. } 8 | 9 | program Project1; // optional 10 | 11 | { The APPTYPE CONSOLE is relevant only on Windows + Delphi. 12 | Because: 13 | - Windows by default doesn't initialize stdin/stdout/stderr, 14 | - and Delphi applications are by default GUI applications. 15 | So Writeln would fail. 16 | This doesn't matter for FPC (where the default is CONSOLE) 17 | or other OSes (where the distinction doesn't exist, all programs have 18 | stdin/stdout/stderr). } 19 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 20 | 21 | begin 22 | Writeln('halo halo'); 23 | 24 | // wait for user input, to not close the terminal started by F9 from Delphi IDE 25 | Readln; 26 | end. 27 | -------------------------------------------------------------------------------- /020_fibonacci_naive/functions_etc.dpr: -------------------------------------------------------------------------------- 1 | { See https://en.wikipedia.org/wiki/Fibonacci_sequence . 2 | This is naive (slow for large numbers) recursive implementation. } 3 | 4 | program functions_etc; 5 | 6 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 7 | 8 | function Fibonacci(const N: Integer): Integer; 9 | begin 10 | Writeln('calculating for ', N); 11 | case N of 12 | 0: Result := 0; 13 | 1: Result := 1; 14 | else Result := Fibonacci(N - 1) + Fibonacci(N - 2); 15 | end; 16 | end; 17 | 18 | var 19 | I: Integer; 20 | begin 21 | for I := 0 to 10 do 22 | Writeln(Fibonacci(I)); 23 | Readln; 24 | end. 25 | -------------------------------------------------------------------------------- /030_fibonacci_optimized/fibonacci_optimized.dpr: -------------------------------------------------------------------------------- 1 | { Fast Fibonacci implementation (but using 32-bit numbers, 2 | so will fail before 50th Fibonacci number). } 3 | 4 | program fibonacci_optimized; 5 | 6 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 7 | 8 | var 9 | FiboValues: array [0..1000] of Integer; 10 | I: Integer; 11 | begin 12 | FiboValues[0] := 0; 13 | FiboValues[1] := 1; 14 | for I := 2 to 40 do 15 | begin 16 | FiboValues[I] := FiboValues[I - 1] + FiboValues[I - 2]; 17 | Writeln('Fibonacci(', I, ') = ', FiboValues[I]); 18 | end; 19 | Readln; 20 | end. 21 | -------------------------------------------------------------------------------- /040_fibonacci_large/fibonacci_large.dpr: -------------------------------------------------------------------------------- 1 | { Fast Fibonacci implementation using 64-bit numbers, 2 | and assertion to gracefully exit when 64-bit range is not enough. } 3 | 4 | program fibonacci_large; 5 | 6 | uses SysUtils; 7 | 8 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 9 | {$assertions on} 10 | 11 | var 12 | FiboValues: array [0..1000] of UInt64; 13 | I: Integer; 14 | begin 15 | FiboValues[0] := 0; 16 | FiboValues[1] := 1; 17 | for I := 2 to 92 do 18 | begin 19 | Assert(Int64(FiboValues[I - 1]) + Int64(FiboValues[I - 2]) < Int64(High(Int64))); 20 | FiboValues[I] := FiboValues[I - 1] + FiboValues[I - 2]; 21 | Writeln('Fibonacci(', I, ') = ', FiboValues[I]); 22 | end; 23 | Readln; 24 | end. 25 | -------------------------------------------------------------------------------- /045_scoped_enums/scoped_enums.dpr: -------------------------------------------------------------------------------- 1 | { Demo of enums and scopedenums in Pascal. } 2 | 3 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 4 | {$scopedenums on} 5 | 6 | uses SysUtils; 7 | 8 | type 9 | TOS = (Linux, Windows, macOS, Android, iOS); 10 | 11 | var 12 | MyFavoriteOs: TOS; 13 | 14 | OrderedOsILike: array of TOS; 15 | // always integer, from 0 16 | 17 | function DoILike(const OS: TOS): Boolean; 18 | begin 19 | Result := OS = MyFavoriteOs; 20 | end; 21 | 22 | function HowMuchDoILike(const OS: TOS): Integer; 23 | var 24 | I: Integer; 25 | begin 26 | Result := -1; // if OS not found in the list 27 | for I := 0 to Length(OrderedOsILike) - 1 do 28 | begin 29 | if OrderedOsILike[I] = OS then 30 | begin 31 | Result := I; 32 | Break; 33 | end; 34 | end; 35 | end; 36 | 37 | begin 38 | SetLength(OrderedOsILike, 5); 39 | Writeln('how many OS on the list? ', Length(OrderedOsILike)); 40 | 41 | // Length(...) = 5 42 | // Low(...) = 0 43 | // High(...) = 4 = Length(...) - 1 44 | OrderedOsILike[0] := TOS.Linux; 45 | OrderedOsILike[1] := TOS.Linux; 46 | OrderedOsILike[2] := TOS.Linux; 47 | OrderedOsILike[3] := TOS.Windows; 48 | OrderedOsILike[4] := TOS.Android; 49 | 50 | MyFavoriteOs := TOS.Linux; 51 | 52 | Writeln('Windows? ', HowMuchDoILike(TOS.Windows)); 53 | Writeln('Linux? ', HowMuchDoILike(TOS.Linux)); 54 | Readln; 55 | end. 56 | -------------------------------------------------------------------------------- /045_scoped_enums/scoped_enums.dproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | {DD559D76-8F73-4F19-9AF7-91E1CF94902C} 4 | scoped_enums.dpr 5 | True 6 | Debug 7 | scoped_enums 8 | 693377 9 | Console 10 | None 11 | 20.2 12 | Win32 13 | 14 | 15 | true 16 | 17 | 18 | true 19 | Base 20 | true 21 | 22 | 23 | true 24 | Base 25 | true 26 | 27 | 28 | true 29 | Base 30 | true 31 | 32 | 33 | true 34 | Base 35 | true 36 | 37 | 38 | true 39 | Base 40 | true 41 | 42 | 43 | true 44 | Base 45 | true 46 | 47 | 48 | true 49 | Base 50 | true 51 | 52 | 53 | true 54 | Base 55 | true 56 | 57 | 58 | false 59 | false 60 | false 61 | false 62 | false 63 | 00400000 64 | scoped_enums 65 | 1033 66 | CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName= 67 | System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) 68 | $(BDS)\bin\delphi_PROJECTICON.ico 69 | $(BDS)\bin\delphi_PROJECTICNS.icns 70 | 71 | 72 | package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey=;minSdkVersion=23;targetSdkVersion=34 73 | Debug 74 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png 75 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png 76 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png 77 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png 78 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png 79 | $(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png 80 | $(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png 81 | $(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png 82 | $(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png 83 | true 84 | true 85 | true 86 | true 87 | true 88 | true 89 | true 90 | true 91 | true 92 | true 93 | $(BDS)\bin\Artwork\Android\FM_NotificationIcon_24x24.png 94 | $(BDS)\bin\Artwork\Android\FM_NotificationIcon_36x36.png 95 | $(BDS)\bin\Artwork\Android\FM_NotificationIcon_48x48.png 96 | $(BDS)\bin\Artwork\Android\FM_NotificationIcon_72x72.png 97 | $(BDS)\bin\Artwork\Android\FM_NotificationIcon_96x96.png 98 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png 99 | 100 | 101 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png 102 | 103 | 104 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png 105 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png 106 | $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_40x40.png 107 | $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_60x60.png 108 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png 109 | $(BDS)\bin\Artwork\iOS\iPad\FM_NotificationIcon_40x40.png 110 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png 111 | 112 | 113 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_1024x1024.png 114 | 115 | 116 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png 117 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png 118 | $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_40x40.png 119 | $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_60x60.png 120 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png 121 | $(BDS)\bin\Artwork\iOS\iPad\FM_NotificationIcon_40x40.png 122 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png 123 | 124 | 125 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) 126 | Debug 127 | CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName) 128 | 1033 129 | 130 | 131 | RELEASE;$(DCC_Define) 132 | 0 133 | false 134 | 0 135 | 136 | 137 | DEBUG;$(DCC_Define) 138 | false 139 | true 140 | true 141 | true 142 | 143 | 144 | 145 | MainSource 146 | 147 | 148 | Base 149 | 150 | 151 | Cfg_1 152 | Base 153 | 154 | 155 | Cfg_2 156 | Base 157 | 158 | 159 | 160 | Delphi.Personality.12 161 | 162 | 163 | 164 | 165 | scoped_enums.dpr 166 | 167 | 168 | 169 | False 170 | True 171 | False 172 | True 173 | True 174 | False 175 | True 176 | False 177 | True 178 | True 179 | True 180 | False 181 | 182 | 183 | 12 184 | 185 | 186 | 187 | 188 | -------------------------------------------------------------------------------- /050_sample_game/Project1.dpr: -------------------------------------------------------------------------------- 1 | program Project1; 2 | 3 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 4 | 5 | uses 6 | SysUtils; 7 | 8 | procedure Cave; forward; 9 | procedure Forest; forward; 10 | procedure Castle; forward; 11 | 12 | procedure Cave; 13 | var 14 | C: Char; 15 | begin 16 | Writeln('You see a dragon. Do you fight? (y / n)'); 17 | 18 | Readln(C); 19 | 20 | case C of 21 | 'y':Writeln('You lost.'); 22 | 'n':begin 23 | Writeln('You ran away.'); 24 | Forest; 25 | end; 26 | else 27 | begin 28 | Writeln('Invalid response, try again'); 29 | Cave; 30 | end; 31 | end; 32 | end; 33 | 34 | procedure Forest; 35 | var 36 | C: Char; 37 | begin 38 | Writeln('You are in the forest'); 39 | Writeln('l - go left'); 40 | Writeln('r - go right'); 41 | 42 | Readln(C); 43 | 44 | case C of 45 | 'l': Castle; 46 | 'r': Cave; 47 | else 48 | begin 49 | Writeln('Invalid response, try again'); 50 | Forest; 51 | end; 52 | end; 53 | end; 54 | 55 | procedure Castle; 56 | var 57 | C: Char; 58 | begin 59 | Writeln('You are in the castle'); 60 | Writeln('b - go back to the forest'); 61 | Writeln('s - stay'); 62 | 63 | Readln(C); 64 | 65 | case C of 66 | 'b':Forest; 67 | 's':begin 68 | Writeln('You married the princess!'); 69 | end; 70 | else 71 | begin 72 | Writeln('Invalid response, try again'); 73 | Forest; 74 | end; 75 | end; 76 | end; 77 | 78 | begin 79 | Forest; 80 | Writeln('The End'); 81 | Readln; 82 | end. 83 | -------------------------------------------------------------------------------- /060_classes_basics/classes_basics.dpr: -------------------------------------------------------------------------------- 1 | program classes_basics; 2 | 3 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 4 | 5 | uses SysUtils; 6 | 7 | type 8 | TCreature = class 9 | // fields 10 | Name: String; 11 | HitPoints: Integer; 12 | // methods 13 | function WillSurviveAttack(AttackDamage: Integer): Boolean; 14 | end; 15 | 16 | function TCreature.WillSurviveAttack(AttackDamage: Integer): Boolean; 17 | begin 18 | Result := HitPoints > AttackDamage; 19 | end; 20 | 21 | var 22 | // 2 instances of class TCreature 23 | Werewolf: TCreature; 24 | Vampire: TCreature; 25 | begin 26 | Werewolf := TCreature.Create; 27 | Werewolf.Name := 'Werewolf'; 28 | Werewolf.HitPoints := 100; 29 | 30 | Vampire := TCreature.Create; 31 | Vampire.Name := 'Vampire'; 32 | Vampire.HitPoints := 50; 33 | 34 | if Werewolf.WillSurviveAttack(20) then 35 | Writeln(Werewolf.Name, ' survived the attack!') 36 | else 37 | Writeln(Werewolf.Name, ' did not survive the attack!'); 38 | 39 | if Vampire.WillSurviveAttack(60) then 40 | Writeln(Vampire.Name, ' survived the attack!') 41 | else 42 | Writeln(Vampire.Name, ' did not survive the attack!'); 43 | 44 | Werewolf.HitPoints := Werewolf.HitPoints - 20; 45 | Vampire.HitPoints := Vampire.HitPoints - 60; 46 | 47 | if Werewolf.WillSurviveAttack(20) then 48 | Writeln(Werewolf.Name, ' survived the attack!') 49 | else 50 | Writeln(Werewolf.Name, ' did not survive the attack!'); 51 | Werewolf.HitPoints := Werewolf.HitPoints - 20; 52 | 53 | if Werewolf.WillSurviveAttack(20) then 54 | Writeln(Werewolf.Name, ' survived the attack!') 55 | else 56 | Writeln(Werewolf.Name, ' did not survive the attack!'); 57 | Werewolf.HitPoints := Werewolf.HitPoints - 20; 58 | if Werewolf.WillSurviveAttack(20) then 59 | Writeln(Werewolf.Name, ' survived the attack!') 60 | else 61 | Writeln(Werewolf.Name, ' did not survive the attack!'); 62 | Werewolf.HitPoints := Werewolf.HitPoints - 20; 63 | if Werewolf.WillSurviveAttack(20) then 64 | Writeln(Werewolf.Name, ' survived the attack!') 65 | else 66 | Writeln(Werewolf.Name, ' did not survive the attack!'); 67 | Werewolf.HitPoints := Werewolf.HitPoints - 20; 68 | if Werewolf.WillSurviveAttack(20) then 69 | Writeln(Werewolf.Name, ' survived the attack!') 70 | else 71 | Writeln(Werewolf.Name, ' did not survive the attack!'); 72 | Werewolf.HitPoints := Werewolf.HitPoints - 20; 73 | if Werewolf.WillSurviveAttack(20) then 74 | Writeln(Werewolf.Name, ' survived the attack!') 75 | else 76 | Writeln(Werewolf.Name, ' did not survive the attack!'); 77 | Werewolf.HitPoints := Werewolf.HitPoints - 20; 78 | if Werewolf.WillSurviveAttack(20) then 79 | Writeln(Werewolf.Name, ' survived the attack!') 80 | else 81 | Writeln(Werewolf.Name, ' did not survive the attack!'); 82 | Werewolf.HitPoints := Werewolf.HitPoints - 20; 83 | if Werewolf.WillSurviveAttack(20) then 84 | Writeln(Werewolf.Name, ' survived the attack!') 85 | else 86 | Writeln(Werewolf.Name, ' did not survive the attack!'); 87 | Werewolf.HitPoints := Werewolf.HitPoints - 20; 88 | if Werewolf.WillSurviveAttack(20) then 89 | Writeln(Werewolf.Name, ' survived the attack!') 90 | else 91 | Writeln(Werewolf.Name, ' did not survive the attack!'); 92 | Werewolf.HitPoints := Werewolf.HitPoints - 20; 93 | 94 | Writeln('at the end, hit points of werewolf: ', Werewolf.HitPoints); 95 | Writeln('at the end, hit points of vampire: ', Vampire.HitPoints); 96 | 97 | if Vampire = nil then 98 | Writeln('Vampire is nil') 99 | else 100 | Writeln('Vampire is not nil'); 101 | 102 | // Free memory 103 | // Werewolf.Free; 104 | // Vampire.Free; 105 | // even better to use FreeAndNil 106 | FreeAndNil(Werewolf); 107 | FreeAndNil(Vampire); 108 | 109 | if Vampire = nil then 110 | Writeln('Vampire is nil') 111 | else 112 | Writeln('Vampire is not nil'); 113 | 114 | Readln; 115 | end. 116 | -------------------------------------------------------------------------------- /065_dangling_pointers_and_copying_refs/Project1.dpr: -------------------------------------------------------------------------------- 1 | program Project1; 2 | 3 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 4 | 5 | uses SysUtils; 6 | 7 | type 8 | TCreature = class 9 | // fields 10 | Name: String; 11 | HitPoints: Integer; 12 | // methods 13 | constructor Create; 14 | function WillSurviveAttack(const Damage: Integer): Boolean; 15 | procedure ZawyjDoKsiezyca; 16 | end; 17 | 18 | TVampyre = class(TCreature) 19 | // fields 20 | FangsPoisonous: Boolean; 21 | end; 22 | 23 | TLocation = class 24 | // fields 25 | Name: String; // '' 26 | Dangerous: Boolean; // false 27 | HasDragon: Boolean; 28 | Creature: TCreature; // nil 29 | I: Integer; // 0 30 | S: Single; // 0.0 31 | // methods 32 | procedure Visit; 33 | end; 34 | 35 | { TLocation } 36 | 37 | procedure TLocation.Visit; 38 | begin 39 | Writeln('Odwiedzasz: ', Name); 40 | end; 41 | 42 | { TCreature } 43 | 44 | constructor TCreature.Create; 45 | begin 46 | // inherited; 47 | HitPoints := 100; 48 | end; 49 | 50 | function TCreature.WillSurviveAttack(const Damage: Integer): Boolean; 51 | begin 52 | Result := Damage < HitPoints; 53 | end; 54 | 55 | procedure TCreature.ZawyjDoKsiezyca; 56 | var 57 | I: Integer; 58 | begin 59 | I := 12; // I, local variable, would be undefined if not initialized! 60 | Writeln('Value of local variable is: ', I); 61 | 62 | // this does not access any field, so would work even when called with Self=nil 63 | Writeln('Awwwwwwwwwwwooooooooooooooooo'); 64 | end; 65 | 66 | { 67 | procedure TObject.Free; 68 | begin 69 | if Self <> nil then 70 | Destroy; 71 | end; 72 | 73 | // the truth: 74 | procedure FreeAndNil(var A: TObject); 75 | var 76 | Tmp: TObject; 77 | begin 78 | Tmp := A; 79 | A := nil; 80 | Tmp.Free; 81 | end; 82 | 83 | // simplification of truth: 84 | procedure FreeAndNil(var A: TObject); 85 | begin 86 | A.Free; 87 | A := nil; 88 | end; 89 | } 90 | 91 | procedure Foo(const C: TCreature); 92 | begin 93 | // C := nil; // this will not compile, cannot change C 94 | 95 | // this will compile, and change C contents, it's OK -- "const" only guards the pointer 96 | C.HitPoints := C.HitPoints - 1; 97 | C.HitPoints := C.HitPoints - 1; 98 | C.HitPoints := C.HitPoints - 1; 99 | C.HitPoints := C.HitPoints - 1; 100 | end; 101 | 102 | var 103 | WerewolfAdditionalReference, Werewolf: TCreature; 104 | begin 105 | // Werewolf.ZawyjDoKsiezyca; // would work, even when Werewolf = nil, but don't call things from nil 106 | 107 | // Werewolf.Free; // would work, even when Werewolf = nil, 108 | 109 | Werewolf := TCreature.Create; 110 | Werewolf.Name := 'Werewolf'; 111 | Werewolf.HitPoints := 100; 112 | Werewolf.ZawyjDoKsiezyca; 113 | 114 | Assert(Werewolf <> nil); 115 | 116 | // this would make a "deep copy", not only copy the pointer 117 | // WerewolfAdditionalReference := TCreature.Create; 118 | // WerewolfAdditionalReference.Name := Werewolf.Name; 119 | // WerewolfAdditionalReference.HitPoints := Werewolf.HitPoints; 120 | 121 | // copies the pointer only 122 | WerewolfAdditionalReference := Werewolf; 123 | 124 | WerewolfAdditionalReference.Name := 'New Wolfie'; 125 | WerewolfAdditionalReference.HitPoints := WerewolfAdditionalReference.HitPoints - 1; 126 | WerewolfAdditionalReference.HitPoints := WerewolfAdditionalReference.HitPoints - 1; 127 | WerewolfAdditionalReference.HitPoints := WerewolfAdditionalReference.HitPoints - 1; 128 | WerewolfAdditionalReference.HitPoints := WerewolfAdditionalReference.HitPoints - 1; 129 | 130 | Werewolf.HitPoints := Werewolf.HitPoints - 1; 131 | Werewolf.HitPoints := Werewolf.HitPoints - 1; 132 | Werewolf.HitPoints := Werewolf.HitPoints - 1; 133 | Werewolf.HitPoints := Werewolf.HitPoints - 1; 134 | 135 | Foo(Werewolf); 136 | 137 | Writeln(Werewolf.Name, ' ',Werewolf.HitPoints); 138 | 139 | // not recommended: 140 | //Werewolf.Destroy; 141 | // not recommended: 142 | //Werewolf.Free; 143 | // recommended: 144 | FreeAndNil(Werewolf); 145 | Assert(Werewolf = nil); 146 | 147 | // this is safe 148 | FreeAndNil(Werewolf); 149 | FreeAndNil(Werewolf); 150 | FreeAndNil(Werewolf); 151 | FreeAndNil(Werewolf); 152 | FreeAndNil(Werewolf); 153 | 154 | Assert(Werewolf = nil); 155 | Assert(WerewolfAdditionalReference <> nil); 156 | 157 | // this would be wrong, WerewolfAdditionalReference is a dangling pointer now 158 | // FreeAndNil(WerewolfAdditionalReference); 159 | 160 | Readln; 161 | end. 162 | -------------------------------------------------------------------------------- /065_dangling_pointers_and_copying_refs/Project1.dproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | {BA1F3646-8482-4558-AB03-D3E6FB9AC94F} 4 | Project1.dpr 5 | True 6 | Debug 7 | Project1 8 | 168065 9 | Console 10 | None 11 | 20.3 12 | Win32 13 | 14 | 15 | true 16 | 17 | 18 | true 19 | Base 20 | true 21 | 22 | 23 | true 24 | Base 25 | true 26 | 27 | 28 | true 29 | Base 30 | true 31 | 32 | 33 | true 34 | Base 35 | true 36 | 37 | 38 | true 39 | Base 40 | true 41 | 42 | 43 | true 44 | Base 45 | true 46 | 47 | 48 | true 49 | Base 50 | true 51 | 52 | 53 | true 54 | Base 55 | true 56 | 57 | 58 | true 59 | Cfg_2 60 | true 61 | true 62 | 63 | 64 | true 65 | Cfg_2 66 | true 67 | true 68 | 69 | 70 | true 71 | Cfg_2 72 | true 73 | true 74 | 75 | 76 | false 77 | false 78 | false 79 | false 80 | false 81 | 00400000 82 | Project1 83 | 1045 84 | CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName= 85 | System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) 86 | $(BDS)\bin\delphi_PROJECTICON.ico 87 | $(BDS)\bin\delphi_PROJECTICNS.icns 88 | 89 | 90 | package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey=;minSdkVersion=23;targetSdkVersion=35 91 | Debug 92 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png 93 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png 94 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png 95 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png 96 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png 97 | $(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png 98 | $(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png 99 | $(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png 100 | $(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png 101 | true 102 | true 103 | true 104 | true 105 | true 106 | true 107 | true 108 | true 109 | true 110 | true 111 | $(BDS)\bin\Artwork\Android\FM_NotificationIcon_24x24.png 112 | $(BDS)\bin\Artwork\Android\FM_NotificationIcon_36x36.png 113 | $(BDS)\bin\Artwork\Android\FM_NotificationIcon_48x48.png 114 | $(BDS)\bin\Artwork\Android\FM_NotificationIcon_72x72.png 115 | $(BDS)\bin\Artwork\Android\FM_NotificationIcon_96x96.png 116 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png 117 | activity-1.7.2.dex.jar;annotation-experimental-1.4.1.dex.jar;annotation-jvm-1.8.1.dex.jar;annotations-13.0.dex.jar;appcompat-1.2.0.dex.jar;appcompat-resources-1.2.0.dex.jar;billing-7.1.1.dex.jar;biometric-1.1.0.dex.jar;browser-1.4.0.dex.jar;cloud-messaging.dex.jar;collection-jvm-1.4.2.dex.jar;concurrent-futures-1.1.0.dex.jar;core-1.15.0.dex.jar;core-common-2.2.0.dex.jar;core-ktx-1.15.0.dex.jar;core-runtime-2.2.0.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;error_prone_annotations-2.9.0.dex.jar;exifinterface-1.3.6.dex.jar;firebase-annotations-16.2.0.dex.jar;firebase-common-20.3.1.dex.jar;firebase-components-17.1.0.dex.jar;firebase-datatransport-18.1.7.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-encoders-proto-16.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.1.3.dex.jar;firebase-installations-interop-17.1.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-23.1.2.dex.jar;fmx.dex.jar;fragment-1.2.5.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;kotlin-stdlib-1.8.22.dex.jar;kotlin-stdlib-common-1.8.22.dex.jar;kotlin-stdlib-jdk7-1.8.22.dex.jar;kotlin-stdlib-jdk8-1.8.22.dex.jar;kotlinx-coroutines-android-1.6.4.dex.jar;kotlinx-coroutines-core-jvm-1.6.4.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.6.2.dex.jar;lifecycle-livedata-2.6.2.dex.jar;lifecycle-livedata-core-2.6.2.dex.jar;lifecycle-runtime-2.6.2.dex.jar;lifecycle-service-2.6.2.dex.jar;lifecycle-viewmodel-2.6.2.dex.jar;lifecycle-viewmodel-savedstate-2.6.2.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;okio-jvm-3.4.0.dex.jar;play-services-ads-22.2.0.dex.jar;play-services-ads-base-22.2.0.dex.jar;play-services-ads-identifier-18.0.0.dex.jar;play-services-ads-lite-22.2.0.dex.jar;play-services-appset-16.0.1.dex.jar;play-services-base-18.5.0.dex.jar;play-services-basement-18.4.0.dex.jar;play-services-cloud-messaging-17.0.1.dex.jar;play-services-location-21.0.1.dex.jar;play-services-maps-18.1.0.dex.jar;play-services-measurement-base-20.1.2.dex.jar;play-services-measurement-sdk-api-20.1.2.dex.jar;play-services-stats-17.0.2.dex.jar;play-services-tasks-18.2.0.dex.jar;print-1.0.0.dex.jar;profileinstaller-1.3.0.dex.jar;room-common-2.2.5.dex.jar;room-runtime-2.2.5.dex.jar;savedstate-1.2.1.dex.jar;sqlite-2.1.0.dex.jar;sqlite-framework-2.1.0.dex.jar;startup-runtime-1.1.1.dex.jar;tracing-1.2.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.1.8.dex.jar;transport-runtime-3.1.8.dex.jar;user-messaging-platform-2.0.0.dex.jar;vectordrawable-1.1.0.dex.jar;vectordrawable-animated-1.1.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.7.0.dex.jar 118 | 119 | 120 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png 121 | activity-1.7.2.dex.jar;annotation-experimental-1.4.1.dex.jar;annotation-jvm-1.8.1.dex.jar;annotations-13.0.dex.jar;appcompat-1.2.0.dex.jar;appcompat-resources-1.2.0.dex.jar;billing-7.1.1.dex.jar;biometric-1.1.0.dex.jar;browser-1.4.0.dex.jar;cloud-messaging.dex.jar;collection-jvm-1.4.2.dex.jar;concurrent-futures-1.1.0.dex.jar;core-1.15.0.dex.jar;core-common-2.2.0.dex.jar;core-ktx-1.15.0.dex.jar;core-runtime-2.2.0.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;error_prone_annotations-2.9.0.dex.jar;exifinterface-1.3.6.dex.jar;firebase-annotations-16.2.0.dex.jar;firebase-common-20.3.1.dex.jar;firebase-components-17.1.0.dex.jar;firebase-datatransport-18.1.7.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-encoders-proto-16.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.1.3.dex.jar;firebase-installations-interop-17.1.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-23.1.2.dex.jar;fmx.dex.jar;fragment-1.2.5.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;kotlin-stdlib-1.8.22.dex.jar;kotlin-stdlib-common-1.8.22.dex.jar;kotlin-stdlib-jdk7-1.8.22.dex.jar;kotlin-stdlib-jdk8-1.8.22.dex.jar;kotlinx-coroutines-android-1.6.4.dex.jar;kotlinx-coroutines-core-jvm-1.6.4.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.6.2.dex.jar;lifecycle-livedata-2.6.2.dex.jar;lifecycle-livedata-core-2.6.2.dex.jar;lifecycle-runtime-2.6.2.dex.jar;lifecycle-service-2.6.2.dex.jar;lifecycle-viewmodel-2.6.2.dex.jar;lifecycle-viewmodel-savedstate-2.6.2.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;okio-jvm-3.4.0.dex.jar;play-services-ads-22.2.0.dex.jar;play-services-ads-base-22.2.0.dex.jar;play-services-ads-identifier-18.0.0.dex.jar;play-services-ads-lite-22.2.0.dex.jar;play-services-appset-16.0.1.dex.jar;play-services-base-18.5.0.dex.jar;play-services-basement-18.4.0.dex.jar;play-services-cloud-messaging-17.0.1.dex.jar;play-services-location-21.0.1.dex.jar;play-services-maps-18.1.0.dex.jar;play-services-measurement-base-20.1.2.dex.jar;play-services-measurement-sdk-api-20.1.2.dex.jar;play-services-stats-17.0.2.dex.jar;play-services-tasks-18.2.0.dex.jar;print-1.0.0.dex.jar;profileinstaller-1.3.0.dex.jar;room-common-2.2.5.dex.jar;room-runtime-2.2.5.dex.jar;savedstate-1.2.1.dex.jar;sqlite-2.1.0.dex.jar;sqlite-framework-2.1.0.dex.jar;startup-runtime-1.1.1.dex.jar;tracing-1.2.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.1.8.dex.jar;transport-runtime-3.1.8.dex.jar;user-messaging-platform-2.0.0.dex.jar;vectordrawable-1.1.0.dex.jar;vectordrawable-animated-1.1.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.7.0.dex.jar 122 | 123 | 124 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png 125 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png 126 | $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_40x40.png 127 | $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_60x60.png 128 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png 129 | $(BDS)\bin\Artwork\iOS\iPad\FM_NotificationIcon_40x40.png 130 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png 131 | 132 | 133 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png 134 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png 135 | $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_40x40.png 136 | $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_60x60.png 137 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png 138 | $(BDS)\bin\Artwork\iOS\iPad\FM_NotificationIcon_40x40.png 139 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png 140 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_1024x1024.png 141 | 142 | 143 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png 144 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png 145 | $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_40x40.png 146 | $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_60x60.png 147 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png 148 | $(BDS)\bin\Artwork\iOS\iPad\FM_NotificationIcon_40x40.png 149 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png 150 | 151 | 152 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) 153 | Debug 154 | CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= 155 | 1033 156 | 157 | 158 | RELEASE;$(DCC_Define) 159 | 0 160 | false 161 | 0 162 | 163 | 164 | DEBUG;$(DCC_Define) 165 | false 166 | true 167 | true 168 | true 169 | 170 | 171 | Debug 172 | 173 | 174 | Debug 175 | 176 | 177 | Debug 178 | 179 | 180 | 181 | MainSource 182 | 183 | 184 | Base 185 | 186 | 187 | Cfg_1 188 | Base 189 | 190 | 191 | Cfg_2 192 | Base 193 | 194 | 195 | 196 | Delphi.Personality.12 197 | 198 | 199 | 200 | 201 | Project1.dpr 202 | 203 | 204 | 205 | False 206 | True 207 | False 208 | False 209 | False 210 | True 211 | False 212 | True 213 | True 214 | True 215 | False 216 | 217 | 218 | 12 219 | 220 | 221 | 222 | 223 | -------------------------------------------------------------------------------- /070_classes_ancestors/classes_ancestors.dpr: -------------------------------------------------------------------------------- 1 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 2 | 3 | uses SysUtils; 4 | 5 | type 6 | TPlayer = class 7 | Poisoned: Boolean; 8 | HitPoints: Integer; 9 | end; 10 | 11 | TCreature = class 12 | // fields 13 | Name: String; 14 | HitPoints: Integer; 15 | procedure Attack(const Player: TPlayer); virtual; 16 | end; 17 | 18 | TVampyre = class(TCreature) 19 | // fields 20 | FangsPoisonous: Boolean; 21 | procedure Attack(const Player: TPlayer); override; 22 | end; 23 | 24 | TRobot = class(TCreature) 25 | Cpu: String; 26 | end; 27 | 28 | TApple = class 29 | 30 | end; 31 | 32 | procedure TCreature.Attack(const Player: TPlayer); 33 | begin 34 | Player.HitPoints := Player.HitPoints - 1; 35 | end; 36 | 37 | procedure TVampyre.Attack(const Player: TPlayer); 38 | begin 39 | inherited; 40 | if FangsPoisonous then 41 | Player.Poisoned := true; 42 | end; 43 | 44 | var 45 | //Vlad, Dracula: TVampyre; 46 | Vlad: TVampyre; 47 | Dracula: TVampyre; 48 | C: array [0..1] of TCreature; 49 | Player: TPlayer; 50 | begin 51 | {$ifndef FPC} ReportMemoryLeaksOnShutdown := true; {$endif} 52 | 53 | Vlad := TVampyre.Create; 54 | Vlad.Name := 'Vlad'; 55 | Vlad.FangsPoisonous := False; 56 | 57 | Dracula := TVampyre.Create; 58 | Dracula.Name := 'Dracula'; 59 | Dracula.FangsPoisonous := True; 60 | 61 | Player := TPlayer.Create; 62 | Player.HitPoints := 100; 63 | 64 | WriteLn('Vlad: ', Vlad.Name, ' ', Vlad.HitPoints, ', FangsPoisonous? ', Vlad.FangsPoisonous); 65 | WriteLn('Dracula: ', Dracula.Name, ' ', Dracula.HitPoints, ', FangsPoisonous? ', Dracula.FangsPoisonous); 66 | 67 | C[0] := Vlad; 68 | C[1] := Dracula; 69 | 70 | // This works, whether Attack is virtual or not. 71 | // Because at compile-time the compiler knows this is TVampyre.Attack. 72 | // Vlad.Attack(Player); 73 | // Vlad.Attack(Player); 74 | // Vlad.Attack(Player); 75 | // Dracula.Attack(Player); 76 | 77 | // This works, just like above, but only when the Attack is virtual. 78 | // At compile-time (if Attack is not virtual) the compiler could only 79 | // determine to call TCreature.Attack. 80 | C[0].Attack(Player); 81 | C[0].Attack(Player); 82 | C[0].Attack(Player); 83 | C[1].Attack(Player); 84 | 85 | Writeln('Player: ', Player.HitPoints, ', Poisoned? ', Player.Poisoned); 86 | 87 | Writeln('C[0] is TCreature: ', C[0] is TCreature); 88 | Writeln('C[0] is TVampyre: ', C[0] is TVampyre); 89 | Writeln('C[0] is TRobot: ', C[0] is TRobot); 90 | // This check makes no sense, because TApple is not a descendant of TCreature. 91 | // It would always be false, compiler assumes it's just an error in your thinking. 92 | // Writeln(C[0] is TApple); 93 | 94 | FreeAndNil(Vlad); 95 | FreeAndNil(Dracula); 96 | FreeAndNil(Player); 97 | 98 | Readln; 99 | end. 100 | 101 | -------------------------------------------------------------------------------- /080_classes_freeing/classes_freeing.dpr: -------------------------------------------------------------------------------- 1 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 2 | 3 | uses SysUtils, Generics.Collections; 4 | 5 | type 6 | TCreature = class 7 | Name: String; 8 | HitPoints: Integer; 9 | end; 10 | 11 | TLocation = class 12 | Creature1, Creature2: TCreature; 13 | constructor Create; 14 | destructor Destroy; override; 15 | end; 16 | 17 | constructor TLocation.Create; 18 | begin 19 | inherited; 20 | Creature1 := TCreature.Create; 21 | Creature2 := TCreature.Create; 22 | end; 23 | 24 | destructor TLocation.Destroy; 25 | begin 26 | FreeAndNil(Creature1); 27 | FreeAndNil(Creature2); 28 | inherited; 29 | end; 30 | 31 | var 32 | MyLocation: TLocation; 33 | begin 34 | {$ifndef FPC} ReportMemoryLeaksOnShutdown := true; {$endif} 35 | MyLocation := TLocation.Create; 36 | try 37 | 38 | finally 39 | FreeAndNil(MyLocation); 40 | end; 41 | Readln; 42 | end. 43 | -------------------------------------------------------------------------------- /090_classes_freeing_lists/80_classes_freeing_lists.dpr: -------------------------------------------------------------------------------- 1 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 2 | 3 | uses SysUtils, Generics.Collections; 4 | 5 | type 6 | TCreature = class 7 | Name: String; 8 | HitPoints: Integer; 9 | end; 10 | 11 | TLocation = class 12 | Creatures: TObjectList; 13 | constructor Create; 14 | destructor Destroy; override; 15 | end; 16 | 17 | constructor TLocation.Create; 18 | begin 19 | inherited; 20 | Creatures := TObjectList.Create(true); 21 | end; 22 | 23 | destructor TLocation.Destroy; 24 | begin 25 | FreeAndNil(Creatures); 26 | inherited; 27 | end; 28 | 29 | var 30 | MyLocation: TLocation; 31 | Werewolf: TCreature; 32 | Vampyre: TCreature; 33 | begin 34 | {$ifndef FPC} ReportMemoryLeaksOnShutdown := true; {$endif} 35 | MyLocation := TLocation.Create; 36 | try 37 | Werewolf := TCreature.Create; 38 | Werewolf.Name := 'Werewolf'; 39 | Werewolf.HitPoints := 100; 40 | MyLocation.Creatures.Add(Werewolf); 41 | 42 | Vampyre := TCreature.Create; 43 | Vampyre.Name := 'Vampyre'; 44 | Vampyre.HitPoints := 50; 45 | MyLocation.Creatures.Add(Vampyre); 46 | 47 | Writeln('Location has creatures: ', MyLocation.Creatures.Count); 48 | finally 49 | FreeAndNil(MyLocation); 50 | end; 51 | 52 | Readln; 53 | end. 54 | 55 | -------------------------------------------------------------------------------- /100_classes_freeing_component/classes_freeing_component.dpr: -------------------------------------------------------------------------------- 1 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 2 | 3 | uses SysUtils, Classes; 4 | 5 | type 6 | TCreature = class(TComponent) 7 | public 8 | Name: String; 9 | HitPoints: Integer; 10 | end; 11 | 12 | TLocation = class(TComponent) 13 | end; 14 | 15 | var 16 | MyLocation: TLocation; 17 | Werewolf: TCreature; 18 | Vampyre: TCreature; 19 | begin 20 | {$ifndef FPC} ReportMemoryLeaksOnShutdown := true; {$endif} 21 | MyLocation := TLocation.Create(nil); 22 | try 23 | Werewolf := TCreature.Create(MyLocation); 24 | Werewolf.Name := 'Werewolf'; 25 | Werewolf.HitPoints := 100; 26 | 27 | Vampyre := TCreature.Create(MyLocation); 28 | Vampyre.Name := 'Vampyre'; 29 | Vampyre.HitPoints := 50; 30 | finally 31 | FreeAndNil(MyLocation); 32 | end; 33 | 34 | Readln; 35 | end. 36 | 37 | -------------------------------------------------------------------------------- /110_game_classes/game_classes.dpr: -------------------------------------------------------------------------------- 1 | program game_classes; 2 | 3 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 4 | 5 | uses SysUtils, Generics.Collections; 6 | 7 | var 8 | HasKey: Boolean; 9 | GameOver: Boolean; 10 | 11 | //type 12 | // TCreature = class 13 | // HitPoints: Integer; 14 | // Name: String; 15 | // end; 16 | 17 | { TLocation ------------------------------------------------------------------ } 18 | 19 | type 20 | TLocation = class 21 | //Creatures: TObjectList; 22 | constructor Create; 23 | destructor Destroy; override; 24 | function BeforeVisit: Boolean; virtual; 25 | procedure CoreVisit; virtual; 26 | end; 27 | 28 | var 29 | CurrentLocation: TLocation; 30 | NewLocation: TLocation; 31 | Castle, Forest, Cave: TLocation; 32 | AllLocations: TObjectList; 33 | 34 | constructor TLocation.Create; 35 | begin 36 | inherited; 37 | //Creatures := TObjectList.Create(true); 38 | end; 39 | 40 | destructor TLocation.Destroy; 41 | begin 42 | //FreeAndNil(Creatures); 43 | inherited; 44 | end; 45 | 46 | procedure TLocation.CoreVisit; 47 | begin 48 | 49 | end; 50 | 51 | function TLocation.BeforeVisit: Boolean; 52 | begin 53 | Result := true; 54 | end; 55 | 56 | { TCastle --------------------------------------------------------------------- } 57 | 58 | type 59 | TCastle = class(TLocation) 60 | function BeforeVisit: Boolean; override; 61 | procedure CoreVisit; override; 62 | end; 63 | 64 | function TCastle.BeforeVisit: Boolean; 65 | begin 66 | Result := HasKey; 67 | if not Result then 68 | Writeln('You don''t have the key to enter the castle!'); 69 | end; 70 | 71 | procedure TCastle.CoreVisit; 72 | var 73 | C: Char; 74 | begin 75 | inherited; 76 | 77 | Writeln('You are in the castle'); 78 | Writeln('b - go back to the forest'); 79 | Writeln('s - stay'); 80 | 81 | Readln(C); 82 | 83 | case C of 84 | 'b': NewLocation := Forest; 85 | 's': begin 86 | Writeln('You married the princess!'); 87 | GameOver := true; 88 | end; 89 | else 90 | begin 91 | Writeln('Invalid response, try again'); 92 | CoreVisit; 93 | end; 94 | end; 95 | end; 96 | 97 | { TCave --------------------------------------------------------------------- } 98 | 99 | type 100 | TCave = class(TLocation) 101 | HasDragon: Boolean; 102 | KeyInLocation: Boolean; 103 | constructor Create; 104 | function BeforeVisit: Boolean; override; 105 | procedure CoreVisit; override; 106 | end; 107 | 108 | constructor TCave.Create; 109 | //var 110 | // Smok: TCreature; 111 | begin 112 | inherited; 113 | // Smok := TCreature.Create; 114 | // Smok.HitPoints := 100; 115 | // Smok.Name := 'Smok'; 116 | // Creatures.Add(Smok); 117 | HasDragon := true; 118 | KeyInLocation := true; 119 | end; 120 | 121 | function TCave.BeforeVisit: Boolean; 122 | begin 123 | if HasDragon then 124 | begin 125 | Writeln('There is a dragon in the cave, you must defeat it first'); 126 | if Random(4) = 0 then 127 | begin 128 | HasDragon := false; 129 | Writeln('The dragon has been defeated'); 130 | Result := true; 131 | end else 132 | begin 133 | Writeln('The dragon is undefeated, it remains in the cave, you flee'); 134 | Result := false; 135 | end; 136 | end else 137 | Result := inherited; 138 | end; 139 | 140 | procedure TCave.CoreVisit; 141 | var 142 | C: Char; 143 | begin 144 | inherited; 145 | 146 | Writeln('You see a chest in the cave. Do you open it (o) or leave (l)?'); 147 | 148 | Readln(C); 149 | 150 | case C of 151 | 'o': begin 152 | if KeyInLocation then 153 | begin 154 | Writeln('You found the key'); 155 | HasKey := true; 156 | KeyInLocation := false; 157 | end else 158 | Writeln('The chest is empty'); 159 | end; 160 | 'l': begin 161 | NewLocation := Forest; 162 | end; 163 | else 164 | begin 165 | Writeln('Invalid response, try again'); 166 | CoreVisit; 167 | end; 168 | end; 169 | end; 170 | 171 | { TForest ---------------------------------------------------------------------- } 172 | 173 | type 174 | TForest = class(TLocation) 175 | procedure CoreVisit; override; 176 | end; 177 | 178 | procedure TForest.CoreVisit; 179 | var 180 | C: Char; 181 | begin 182 | Writeln('You are in the forest'); 183 | Writeln('l - go left'); 184 | Writeln('r - go right'); 185 | 186 | Readln(C); 187 | 188 | case C of 189 | 'l': NewLocation := Castle; 190 | 'r': NewLocation := Cave; 191 | else 192 | begin 193 | Writeln('Invalid response, try again'); 194 | CoreVisit; 195 | end; 196 | end; 197 | end; 198 | 199 | begin 200 | {$ifndef FPC} ReportMemoryLeaksOnShutdown := true; {$endif} 201 | Randomize; 202 | 203 | AllLocations := TObjectList.Create(true); 204 | 205 | Cave := TCave.Create; 206 | AllLocations.Add(Cave); 207 | 208 | Forest := TForest.Create; 209 | AllLocations.Add(Forest); 210 | 211 | Castle := TCastle.Create; 212 | AllLocations.Add(Castle); 213 | 214 | CurrentLocation := Forest; // start 215 | 216 | repeat 217 | if NewLocation <> nil then 218 | begin 219 | if NewLocation.BeforeVisit then 220 | CurrentLocation := NewLocation; 221 | NewLocation := nil; 222 | end; 223 | CurrentLocation.CoreVisit; 224 | until GameOver; 225 | 226 | FreeAndNil(AllLocations); 227 | 228 | Readln; 229 | end. 230 | -------------------------------------------------------------------------------- /120_simple_properties_example/simple_properties_example.dpr: -------------------------------------------------------------------------------- 1 | program simple_properties_example; 2 | 3 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 4 | 5 | uses SysUtils; 6 | 7 | type 8 | {$M+} // make it explicit that RTTI for TCreature should be generated 9 | TCreature = class 10 | strict private 11 | FHitPoints: Integer; 12 | procedure SetHitPoints(const Value: Integer); 13 | public 14 | const 15 | DefaultHitPoints = 100; 16 | constructor Create; 17 | published 18 | property HitPoints: Integer read FHitPoints write SetHitPoints 19 | default DefaultHitPoints; 20 | end; 21 | 22 | { TCreature } 23 | 24 | constructor TCreature.Create; 25 | begin 26 | inherited; 27 | FHitPoints := DefaultHitPoints; 28 | end; 29 | 30 | procedure TCreature.SetHitPoints(const Value: Integer); 31 | begin 32 | if FHitPoints <> Value then 33 | begin 34 | if (FHitPoints > 0) and (Value <= 0) then 35 | Writeln('Creature dying!'); 36 | if (FHitPoints <= 0) and (Value > 0) then 37 | raise Exception.Create('Not allowed to resurrect the creature'); 38 | FHitPoints := Value; 39 | end; 40 | end; 41 | 42 | var 43 | Werewolf: TCreature; 44 | I: Integer; 45 | begin 46 | Werewolf := TCreature.Create; 47 | try 48 | for I := 1 to 20 do 49 | begin 50 | Werewolf.HitPoints := Werewolf.HitPoints - 10; 51 | Writeln('Damaged by 10, now hp ', Werewolf.HitPoints); 52 | end; 53 | finally 54 | FreeAndNil(Werewolf); 55 | end; 56 | Readln; 57 | end. 58 | -------------------------------------------------------------------------------- /125_properties_setter_limits/properties_setter_limits.dpr: -------------------------------------------------------------------------------- 1 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 2 | 3 | uses 4 | SysUtils; 5 | 6 | type 7 | TMyClass = class 8 | strict private 9 | FMyInt: Integer; // F like "field" 10 | // Ctrl + Shift + C ("c" like "completion") 11 | function GetMyInt: Integer; 12 | procedure SetMyInt(const Value: Integer); 13 | public 14 | procedure Attack; 15 | { Setting limits the value to 0..1000 * 1000 } 16 | property MyInt: Integer read GetMyInt write SetMyInt; 17 | end; 18 | 19 | procedure TMyClass.Attack; 20 | begin 21 | FMyInt := FMyInt + 1; 22 | end; 23 | 24 | // getter 25 | function TMyClass.GetMyInt: Integer; 26 | begin 27 | Result := FMyInt; 28 | end; 29 | 30 | // setter 31 | procedure TMyClass.SetMyInt(const Value: Integer); 32 | begin 33 | FMyInt := Value; 34 | if FMyInt < 0 then 35 | FMyInt := 0; 36 | if FMyInt > 1000 * 1000 then 37 | FMyInt := 1000 * 1000; 38 | end; 39 | 40 | var 41 | C: TMyClass; 42 | begin 43 | C := TMyClass.Create; 44 | Writeln(C.MyInt); // guaranteed 0 45 | C.MyInt := 123; 46 | Writeln(C.MyInt); 47 | C.MyInt := -1; 48 | Writeln(C.MyInt); 49 | FreeAndNil(C); 50 | 51 | Readln; 52 | end. 53 | -------------------------------------------------------------------------------- /130_array_properties/array_properties.dpr: -------------------------------------------------------------------------------- 1 | program array_properties; 2 | 3 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 4 | 5 | uses SysUtils; 6 | 7 | type 8 | TChildCreature = class 9 | Name: String; 10 | end; 11 | 12 | TCreature = class 13 | strict private 14 | FMyChildren: array[1..10] of TChildCreature; 15 | FVoices: array[1..10] of String; 16 | function GetChildren(const Index: Integer): TChildCreature; 17 | function GetVoices(const Index: Integer): String; 18 | public 19 | Name: String; 20 | constructor Create; 21 | destructor Destroy; override; 22 | property Children[const Index: Integer]: TChildCreature read GetChildren; default; 23 | property Voices[const Index: Integer]: String read GetVoices; 24 | end; 25 | 26 | { TCreature } 27 | 28 | constructor TCreature.Create; 29 | var 30 | I: Integer; 31 | begin 32 | inherited; 33 | for I := 1 to 10 do 34 | begin 35 | FMyChildren[I] := TChildCreature.Create; 36 | FMyChildren[I].Name := 'Child' + IntToStr(I); 37 | FVoices[I] := 'Voice' + IntToStr(I); 38 | end; 39 | end; 40 | 41 | destructor TCreature.Destroy; 42 | var 43 | I: Integer; 44 | begin 45 | for I := 1 to 10 do 46 | FreeAndNil(FMyChildren[I]); 47 | inherited; 48 | end; 49 | 50 | function TCreature.GetChildren(const Index: Integer): TChildCreature; 51 | begin 52 | Result := FMyChildren[Index]; 53 | end; 54 | 55 | function TCreature.GetVoices(const Index: Integer): String; 56 | begin 57 | Result := FVoices[Index]; 58 | end; 59 | 60 | var 61 | Werewolf: TCreature; 62 | I: Integer; 63 | begin 64 | Werewolf := TCreature.Create; 65 | try 66 | for I := 1 to 10 do 67 | begin 68 | Writeln(Werewolf.Voices[I]); 69 | Writeln(Werewolf.Children[I].Name); 70 | Writeln(Werewolf[I].Name); 71 | end; 72 | finally 73 | FreeAndNil(Werewolf); 74 | end; 75 | Readln; 76 | end. 77 | -------------------------------------------------------------------------------- /135_modules_include_files/UnitCreature.pas: -------------------------------------------------------------------------------- 1 | unit UnitCreature; 2 | 3 | interface 4 | 5 | uses Classes, UnitCreatureChild; 6 | 7 | type 8 | TCreature = class 9 | private 10 | FMyChildren: array[1..10] of TChildCreature; 11 | //FVoices: array[1..10] of String; 12 | function GetChildren(const Index: Integer): TChildCreature; 13 | function GetVoices(const Index: Integer): String; 14 | protected 15 | MyProtectedField: Integer; 16 | public 17 | Name: String; 18 | constructor Create; 19 | destructor Destroy; override; 20 | property Children[const Index: Integer]: TChildCreature read GetChildren; default; 21 | property Voices[const Index: Integer]: String read GetVoices; 22 | end; 23 | 24 | implementation 25 | 26 | uses SysUtils; 27 | 28 | var 29 | ChildrenCounter: Integer; 30 | 31 | { TCreature } 32 | 33 | constructor TCreature.Create; 34 | var 35 | I: Integer; 36 | begin 37 | inherited; 38 | Name := 'My Creature'; 39 | for I := 1 to 10 do 40 | begin 41 | Inc(ChildrenCounter); 42 | FMyChildren[I] := TChildCreature.Create(nil); 43 | FMyChildren[I].Parent := Self; 44 | FMyChildren[I].Name := 'Child' + IntToStr(I); 45 | //FVoices[I] := 'Voice' + IntToStr(I); 46 | end; 47 | end; 48 | 49 | destructor TCreature.Destroy; 50 | var 51 | I: Integer; 52 | begin 53 | for I := 1 to 10 do 54 | FreeAndNil(FMyChildren[I]); 55 | inherited; 56 | end; 57 | 58 | function TCreature.GetChildren(const Index: Integer): TChildCreature; 59 | begin 60 | Result := FMyChildren[Index]; 61 | end; 62 | 63 | function TCreature.GetVoices(const Index: Integer): String; 64 | begin 65 | Result := 'VoiceName' + IntToStr(Index); 66 | //FVoices[Index]; 67 | end; 68 | 69 | initialization 70 | finalization 71 | Writeln('Creature children created: ', ChildrenCounter); 72 | end. 73 | -------------------------------------------------------------------------------- /135_modules_include_files/UnitCreatureChild.pas: -------------------------------------------------------------------------------- 1 | unit UnitCreatureChild; 2 | 3 | interface 4 | 5 | uses Classes; 6 | 7 | type 8 | TMyCreatureType = ( 9 | One, 10 | Two 11 | // rather weird usage of include file, but possible 12 | {$include myxxx.inc} 13 | ); 14 | 15 | type 16 | TChildCreature = class(TComponent) 17 | public 18 | MyType: TMyCreatureType; 19 | Name: String; 20 | Parent: TObject; //< Always must be TCreature 21 | function ParentName: String; 22 | end; 23 | 24 | implementation 25 | 26 | uses UnitCreature; 27 | 28 | function TChildCreature.ParentName: String; 29 | begin 30 | Result := (Parent as TCreature).Name; 31 | end; 32 | 33 | { TWerewolf } 34 | 35 | type 36 | TWerewolf = class(TCreature) 37 | procedure Howl; 38 | end; 39 | 40 | procedure TWerewolf.Howl; 41 | begin 42 | // accessing protected is OK 43 | Writeln(MyProtectedField); 44 | end; 45 | 46 | end. 47 | -------------------------------------------------------------------------------- /135_modules_include_files/modules_include_files.dpr: -------------------------------------------------------------------------------- 1 | program array_properties; 2 | 3 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 4 | 5 | uses 6 | SysUtils, UnitCreature, UnitCreatureChild; 7 | 8 | var 9 | Werewolf: TCreature; 10 | begin 11 | Werewolf := TCreature.Create; 12 | try 13 | finally 14 | FreeAndNil(Werewolf); 15 | end; 16 | 17 | Werewolf := TCreature.Create; 18 | try 19 | //Werewolf.MyProtectedField := 12; // not possible 20 | finally 21 | FreeAndNil(Werewolf); 22 | end; 23 | 24 | Werewolf := TCreature.Create; 25 | try 26 | finally 27 | FreeAndNil(Werewolf); 28 | end; 29 | 30 | Readln; 31 | end. 32 | -------------------------------------------------------------------------------- /135_modules_include_files/myxxx.inc: -------------------------------------------------------------------------------- 1 | , Three, Four 2 | -------------------------------------------------------------------------------- /140_forms_etc/UnitDM.dfm: -------------------------------------------------------------------------------- 1 | object DM: TDM 2 | Height = 480 3 | Width = 640 4 | end 5 | -------------------------------------------------------------------------------- /140_forms_etc/UnitDM.pas: -------------------------------------------------------------------------------- 1 | unit UnitDM; 2 | 3 | interface 4 | 5 | uses 6 | System.SysUtils, System.Classes; 7 | 8 | type 9 | TDM = class(TDataModule) 10 | private 11 | { Private declarations } 12 | public 13 | { Public declarations } 14 | end; 15 | 16 | var 17 | DM: TDM; 18 | 19 | implementation 20 | 21 | {%CLASSGROUP 'FMX.Controls.TControl'} 22 | 23 | {$R *.dfm} 24 | 25 | end. 26 | -------------------------------------------------------------------------------- /140_forms_etc/UnitFormAutoCreated.fmx: -------------------------------------------------------------------------------- 1 | object FormAutoCreated: TFormAutoCreated 2 | Left = 0 3 | Top = 0 4 | Caption = 'Form1' 5 | ClientHeight = 480 6 | ClientWidth = 640 7 | FormFactor.Width = 320 8 | FormFactor.Height = 480 9 | FormFactor.Devices = [Desktop] 10 | DesignerMasterStyle = 0 11 | object Label1: TLabel 12 | Position.X = 32.000000000000000000 13 | Position.Y = 24.000000000000000000 14 | Text = 'Form Auto-Created' 15 | TabOrder = 1 16 | end 17 | object ButtonClose: TButton 18 | Position.X = 32.000000000000000000 19 | Position.Y = 64.000000000000000000 20 | TabOrder = 2 21 | Text = 'Close' 22 | TextSettings.Trimming = None 23 | OnClick = ButtonCloseClick 24 | end 25 | object Button1: TButton 26 | Position.X = 32.000000000000000000 27 | Position.Y = 112.000000000000000000 28 | Size.Width = 193.000000000000000000 29 | Size.Height = 22.000000000000000000 30 | Size.PlatformDefault = False 31 | TabOrder = 3 32 | Text = 'New Instance of AutoCreated' 33 | TextSettings.Trimming = None 34 | OnClick = Button1Click 35 | end 36 | object Button2: TButton 37 | Position.X = 32.000000000000000000 38 | Position.Y = 152.000000000000000000 39 | Size.Width = 193.000000000000000000 40 | Size.Height = 22.000000000000000000 41 | Size.PlatformDefault = False 42 | TabOrder = 4 43 | Text = 'New Instance of Not Auto Created' 44 | TextSettings.Trimming = None 45 | OnClick = Button2Click 46 | end 47 | end 48 | -------------------------------------------------------------------------------- /140_forms_etc/UnitFormAutoCreated.pas: -------------------------------------------------------------------------------- 1 | unit UnitFormAutoCreated; 2 | 3 | interface 4 | 5 | uses 6 | System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, 7 | FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, 8 | FMX.Controls.Presentation, FMX.StdCtrls; 9 | 10 | type 11 | TFormAutoCreated = class(TForm) 12 | Label1: TLabel; 13 | ButtonClose: TButton; 14 | Button1: TButton; 15 | Button2: TButton; 16 | procedure ButtonCloseClick(Sender: TObject); 17 | procedure Button2Click(Sender: TObject); 18 | procedure Button1Click(Sender: TObject); 19 | private 20 | { Private declarations } 21 | public 22 | { Public declarations } 23 | end; 24 | 25 | var 26 | FormAutoCreated: TFormAutoCreated; 27 | 28 | implementation 29 | 30 | uses UnitFormNotAutoCreated; 31 | 32 | {$R *.fmx} 33 | 34 | procedure TFormAutoCreated.Button1Click(Sender: TObject); 35 | var 36 | MyNewForm: TFormAutoCreated; 37 | begin 38 | MyNewForm := TFormAutoCreated.Create(Application); 39 | MyNewForm.Show; 40 | end; 41 | 42 | procedure TFormAutoCreated.Button2Click(Sender: TObject); 43 | var 44 | MyNewForm: TFormNotAutoCreated; 45 | begin 46 | MyNewForm := TFormNotAutoCreated.Create(Application); 47 | MyNewForm.Show; 48 | end; 49 | 50 | procedure TFormAutoCreated.ButtonCloseClick(Sender: TObject); 51 | begin 52 | Close; 53 | end; 54 | 55 | end. 56 | -------------------------------------------------------------------------------- /140_forms_etc/UnitFormNotAutoCreated.fmx: -------------------------------------------------------------------------------- 1 | object FormNotAutoCreated: TFormNotAutoCreated 2 | Left = 0 3 | Top = 0 4 | Caption = 'Form1' 5 | ClientHeight = 480 6 | ClientWidth = 640 7 | FormFactor.Width = 320 8 | FormFactor.Height = 480 9 | FormFactor.Devices = [Desktop] 10 | DesignerMasterStyle = 0 11 | object Label1: TLabel 12 | Position.X = 80.000000000000000000 13 | Position.Y = 88.000000000000000000 14 | Size.Width = 217.000000000000000000 15 | Size.Height = 65.000000000000000000 16 | Size.PlatformDefault = False 17 | Text = 'Form Not Auto Created' 18 | TabOrder = 0 19 | end 20 | object ButtonClose: TButton 21 | Position.X = 80.000000000000000000 22 | Position.Y = 192.000000000000000000 23 | TabOrder = 1 24 | Text = 'Close' 25 | TextSettings.Trimming = None 26 | OnClick = ButtonCloseClick 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /140_forms_etc/UnitFormNotAutoCreated.pas: -------------------------------------------------------------------------------- 1 | unit UnitFormNotAutoCreated; 2 | 3 | interface 4 | 5 | uses 6 | System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, 7 | FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls, 8 | FMX.Controls.Presentation; 9 | 10 | type 11 | TFormNotAutoCreated = class(TForm) 12 | Label1: TLabel; 13 | ButtonClose: TButton; 14 | procedure ButtonCloseClick(Sender: TObject); 15 | private 16 | { Private declarations } 17 | public 18 | { Public declarations } 19 | end; 20 | 21 | var 22 | FormNotAutoCreated: TFormNotAutoCreated; 23 | 24 | implementation 25 | 26 | {$R *.fmx} 27 | 28 | procedure TFormNotAutoCreated.ButtonCloseClick(Sender: TObject); 29 | begin 30 | Close; 31 | end; 32 | 33 | end. 34 | -------------------------------------------------------------------------------- /140_forms_etc/UnitFormNotAutoCreatedDescendant.fmx: -------------------------------------------------------------------------------- 1 | inherited FormNotAutoCreatedDescendant: TFormNotAutoCreatedDescendant 2 | Caption = 'FormNotAutoCreated1' 3 | DesignerMasterStyle = 0 4 | inherited Label1: TLabel 5 | Position.X = 184.000000000000000000 6 | end 7 | object Button1: TButton 8 | Position.X = 96.000000000000000000 9 | Position.Y = 264.000000000000000000 10 | Size.Width = 201.000000000000000000 11 | Size.Height = 22.000000000000000000 12 | Size.PlatformDefault = False 13 | TabOrder = 3 14 | Text = 'New button in inherited' 15 | TextSettings.Trimming = None 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /140_forms_etc/UnitFormNotAutoCreatedDescendant.pas: -------------------------------------------------------------------------------- 1 | unit UnitFormNotAutoCreatedDescendant; 2 | 3 | interface 4 | 5 | uses 6 | System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, 7 | FMX.Types, FMX.Graphics, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.StdCtrls, 8 | UnitFormNotAutoCreated, FMX.Controls.Presentation; 9 | 10 | type 11 | TFormNotAutoCreatedDescendant = class(TFormNotAutoCreated) 12 | Button1: TButton; 13 | private 14 | { Private declarations } 15 | public 16 | { Public declarations } 17 | end; 18 | 19 | var 20 | FormNotAutoCreatedDescendant: TFormNotAutoCreatedDescendant; 21 | 22 | implementation 23 | 24 | {$R *.fmx} 25 | 26 | end. 27 | -------------------------------------------------------------------------------- /140_forms_etc/UnitFormUsingFrames.fmx: -------------------------------------------------------------------------------- 1 | object FormUsingFrames: TFormUsingFrames 2 | Left = 0 3 | Top = 0 4 | Caption = 'Form1' 5 | ClientHeight = 780 6 | ClientWidth = 1053 7 | FormFactor.Width = 320 8 | FormFactor.Height = 480 9 | FormFactor.Devices = [Desktop] 10 | DesignerMasterStyle = 0 11 | inline FrameUsingFrames1: TFrameUsingFrames 12 | Position.X = 48.000000000000000000 13 | Position.Y = 32.000000000000000000 14 | Size.Width = 545.000000000000000000 15 | Size.Height = 465.000000000000000000 16 | Size.PlatformDefault = False 17 | end 18 | inline FrameUsingFrames2: TFrameUsingFrames 19 | Position.X = 601.000000000000000000 20 | Position.Y = 32.000000000000000000 21 | Size.Width = 816.000000000000000000 22 | Size.Height = 465.000000000000000000 23 | Size.PlatformDefault = False 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /140_forms_etc/UnitFormUsingFrames.pas: -------------------------------------------------------------------------------- 1 | unit UnitFormUsingFrames; 2 | 3 | interface 4 | 5 | uses 6 | System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, 7 | FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, 8 | UnitFrameUsingFrames; 9 | 10 | type 11 | TFormUsingFrames = class(TForm) 12 | FrameUsingFrames1: TFrameUsingFrames; 13 | FrameUsingFrames2: TFrameUsingFrames; 14 | private 15 | { Private declarations } 16 | public 17 | { Public declarations } 18 | end; 19 | 20 | var 21 | FormUsingFrames: TFormUsingFrames; 22 | 23 | implementation 24 | 25 | {$R *.fmx} 26 | 27 | end. 28 | -------------------------------------------------------------------------------- /140_forms_etc/UnitFrame.fmx: -------------------------------------------------------------------------------- 1 | object MyFrame: TMyFrame 2 | Size.Width = 199.000000000000000000 3 | Size.Height = 146.000000000000000000 4 | Size.PlatformDefault = False 5 | object Panel1: TPanel 6 | Align = Client 7 | Size.Width = 199.000000000000000000 8 | Size.Height = 146.000000000000000000 9 | Size.PlatformDefault = False 10 | TabOrder = 0 11 | object Button1: TButton 12 | Position.X = 16.000000000000000000 13 | Position.Y = 72.000000000000000000 14 | TabOrder = 2 15 | Text = 'Button1' 16 | TextSettings.Trimming = None 17 | end 18 | object Button2: TButton 19 | Position.X = 16.000000000000000000 20 | Position.Y = 104.000000000000000000 21 | TabOrder = 3 22 | Text = 'Button2' 23 | TextSettings.Trimming = None 24 | end 25 | object CheckBox1: TCheckBox 26 | Position.X = 16.000000000000000000 27 | Position.Y = 40.000000000000000000 28 | TabOrder = 0 29 | Text = 'CheckBox1' 30 | end 31 | object Label1: TLabel 32 | Position.X = 16.000000000000000000 33 | Position.Y = 8.000000000000000000 34 | Text = 'I'#39'm frame' 35 | TabOrder = 4 36 | end 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /140_forms_etc/UnitFrame.pas: -------------------------------------------------------------------------------- 1 | unit UnitFrame; 2 | 3 | interface 4 | 5 | uses 6 | System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, 7 | FMX.Types, FMX.Graphics, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.StdCtrls, 8 | FMX.Controls.Presentation; 9 | 10 | type 11 | TMyFrame = class(TFrame) 12 | Panel1: TPanel; 13 | Button1: TButton; 14 | Button2: TButton; 15 | CheckBox1: TCheckBox; 16 | Label1: TLabel; 17 | private 18 | { Private declarations } 19 | public 20 | { Public declarations } 21 | end; 22 | 23 | implementation 24 | 25 | {$R *.fmx} 26 | 27 | end. 28 | -------------------------------------------------------------------------------- /140_forms_etc/UnitFrameUsingFrames.fmx: -------------------------------------------------------------------------------- 1 | object FrameUsingFrames: TFrameUsingFrames 2 | Size.Width = 809.000000000000000000 3 | Size.Height = 646.000000000000000000 4 | Size.PlatformDefault = False 5 | inline MyFrame1: TMyFrame 6 | Position.X = 56.000000000000000000 7 | Position.Y = 40.000000000000000000 8 | Size.Width = 199.000000000000000000 9 | Size.Height = 146.000000000000000000 10 | Size.PlatformDefault = False 11 | end 12 | inline MyFrame2: TMyFrame 13 | Position.X = 328.000000000000000000 14 | Position.Y = 56.000000000000000000 15 | Size.Width = 199.000000000000000000 16 | Size.Height = 146.000000000000000000 17 | Size.PlatformDefault = False 18 | end 19 | inline MyFrame3: TMyFrame 20 | Position.X = 56.000000000000000000 21 | Position.Y = 248.000000000000000000 22 | Size.Width = 199.000000000000000000 23 | Size.Height = 146.000000000000000000 24 | Size.PlatformDefault = False 25 | end 26 | inline MyFrame4: TMyFrame 27 | Position.X = 328.000000000000000000 28 | Position.Y = 256.000000000000000000 29 | Size.Width = 199.000000000000000000 30 | Size.Height = 146.000000000000000000 31 | Size.PlatformDefault = False 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /140_forms_etc/UnitFrameUsingFrames.pas: -------------------------------------------------------------------------------- 1 | unit UnitFrameUsingFrames; 2 | 3 | interface 4 | 5 | uses 6 | System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, 7 | FMX.Types, FMX.Graphics, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.StdCtrls, 8 | UnitFrame; 9 | 10 | type 11 | TFrameUsingFrames = class(TFrame) 12 | MyFrame1: TMyFrame; 13 | MyFrame2: TMyFrame; 14 | MyFrame3: TMyFrame; 15 | MyFrame4: TMyFrame; 16 | private 17 | { Private declarations } 18 | public 19 | { Public declarations } 20 | end; 21 | 22 | implementation 23 | 24 | {$R *.fmx} 25 | 26 | end. 27 | -------------------------------------------------------------------------------- /140_forms_etc/forms_etc.dpr: -------------------------------------------------------------------------------- 1 | program forms_etc; 2 | 3 | uses 4 | System.StartUpCopy, 5 | FMX.Forms, 6 | UnitFormAutoCreated in 'UnitFormAutoCreated.pas' {FormAutoCreated}, 7 | UnitDM in 'UnitDM.pas' {DM: TDataModule}, 8 | UnitFormNotAutoCreated in 'UnitFormNotAutoCreated.pas' {FormNotAutoCreated}, 9 | UnitFormNotAutoCreatedDescendant in 'UnitFormNotAutoCreatedDescendant.pas' {FormNotAutoCreatedDescendant}, 10 | UnitFrame in 'UnitFrame.pas' {MyFrame: TFrame}, 11 | UnitFrameUsingFrames in 'UnitFrameUsingFrames.pas' {FrameUsingFrames: TFrame}, 12 | UnitFormUsingFrames in 'UnitFormUsingFrames.pas' {FormUsingFrames}; 13 | 14 | {$R *.res} 15 | 16 | begin 17 | Application.Initialize; 18 | Application.CreateForm(TDM, DM); 19 | Application.CreateForm(TFormAutoCreated, FormAutoCreated); 20 | Application.CreateForm(TFormNotAutoCreatedDescendant, FormNotAutoCreatedDescendant); 21 | Application.CreateForm(TFormUsingFrames, FormUsingFrames); 22 | Application.Run; 23 | end. 24 | -------------------------------------------------------------------------------- /140_forms_etc/forms_etc.res: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/modern-pascal/modern-pascal-course/c82a559683cd0fa4a7666d7b0beb324d645d2cfb/140_forms_etc/forms_etc.res -------------------------------------------------------------------------------- /150_data_module_using_components/Project1.dpr: -------------------------------------------------------------------------------- 1 | program Project1; 2 | 3 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 4 | 5 | {$R *.res} 6 | 7 | uses 8 | System.SysUtils, 9 | UnitDataModule1 in 'UnitDataModule1.pas' {DataModule1: TDataModule}, 10 | Creature in 'component\Creature.pas'; 11 | 12 | begin 13 | {$ifndef FPC} ReportMemoryLeaksOnShutdown := true; {$endif} 14 | 15 | DataModule1 := TDataModule1.Create(nil); 16 | try 17 | Writeln(DataModule1.Werewolf.Name, ' ', DataModule1.Werewolf.HitPoints); 18 | Writeln(DataModule1.Vampyre.Name, ' ', DataModule1.Vampyre.HitPoints); 19 | finally 20 | FreeAndNil(DataModule1); 21 | end; 22 | 23 | Readln; 24 | end. 25 | -------------------------------------------------------------------------------- /150_data_module_using_components/Project1.res: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/modern-pascal/modern-pascal-course/c82a559683cd0fa4a7666d7b0beb324d645d2cfb/150_data_module_using_components/Project1.res -------------------------------------------------------------------------------- /150_data_module_using_components/UnitDataModule1.dfm: -------------------------------------------------------------------------------- 1 | object DataModule1: TDataModule1 2 | Height = 480 3 | Width = 640 4 | object Werewolf: TCreature 5 | HitPoints = 100 6 | Left = 224 7 | Top = 128 8 | end 9 | object Vampyre: TCreature 10 | HitPoints = 50 11 | Left = 176 12 | Top = 232 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /150_data_module_using_components/UnitDataModule1.pas: -------------------------------------------------------------------------------- 1 | unit UnitDataModule1; 2 | 3 | interface 4 | 5 | uses 6 | System.SysUtils, System.Classes, System.Bluetooth, System.Bluetooth.Components, 7 | Creature; 8 | 9 | type 10 | TDataModule1 = class(TDataModule) 11 | Werewolf: TCreature; 12 | Vampyre: TCreature; 13 | private 14 | { Private declarations } 15 | public 16 | { Public declarations } 17 | end; 18 | 19 | var 20 | DataModule1: TDataModule1; 21 | 22 | implementation 23 | 24 | {%CLASSGROUP 'System.Classes.TPersistent'} 25 | 26 | {$R *.dfm} 27 | 28 | end. 29 | -------------------------------------------------------------------------------- /150_data_module_using_components/component/Creature.pas: -------------------------------------------------------------------------------- 1 | unit Creature; 2 | 3 | interface 4 | 5 | uses 6 | SysUtils, System.Classes; 7 | 8 | type 9 | TCreature = class(TComponent) 10 | private 11 | FHitPoints: Integer; 12 | procedure SetHitPoints(const Value: Integer); 13 | { Private declarations } 14 | protected 15 | { Protected declarations } 16 | public 17 | function IsAlive: Boolean; 18 | published 19 | property HitPoints: Integer read FHitPoints write SetHitPoints; 20 | end; 21 | 22 | procedure Register; 23 | 24 | implementation 25 | 26 | procedure Register; 27 | begin 28 | RegisterComponents('Samples', [TCreature]); 29 | end; 30 | 31 | { TCreature } 32 | 33 | function TCreature.IsAlive: Boolean; 34 | begin 35 | Result := HitPoints > 0; 36 | end; 37 | 38 | procedure TCreature.SetHitPoints(const Value: Integer); 39 | begin 40 | FHitPoints := Value; 41 | end; 42 | 43 | end. 44 | -------------------------------------------------------------------------------- /150_data_module_using_components/component/my_creature_package.dpk: -------------------------------------------------------------------------------- 1 | package my_creature_package; 2 | 3 | {$R *.res} 4 | {$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} 5 | {$ALIGN 8} 6 | {$ASSERTIONS ON} 7 | {$BOOLEVAL OFF} 8 | {$DEBUGINFO OFF} 9 | {$EXTENDEDSYNTAX ON} 10 | {$IMPORTEDDATA ON} 11 | {$IOCHECKS ON} 12 | {$LOCALSYMBOLS ON} 13 | {$LONGSTRINGS ON} 14 | {$OPENSTRINGS ON} 15 | {$OPTIMIZATION OFF} 16 | {$OVERFLOWCHECKS ON} 17 | {$RANGECHECKS ON} 18 | {$REFERENCEINFO ON} 19 | {$SAFEDIVIDE OFF} 20 | {$STACKFRAMES ON} 21 | {$TYPEDADDRESS OFF} 22 | {$VARSTRINGCHECKS ON} 23 | {$WRITEABLECONST OFF} 24 | {$MINENUMSIZE 1} 25 | {$IMAGEBASE $400000} 26 | {$DEFINE DEBUG} 27 | {$ENDIF IMPLICITBUILDING} 28 | {$IMPLICITBUILD ON} 29 | 30 | requires 31 | rtl; 32 | 33 | contains 34 | Creature in 'Creature.pas'; 35 | 36 | end. 37 | -------------------------------------------------------------------------------- /150_data_module_using_components/component/my_creature_package.dproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | {81DF2C93-8950-4517-AD32-9FBFA17AEEF0} 4 | my_creature_package.dpk 5 | 20.3 6 | None 7 | True 8 | Debug 9 | Win32 10 | my_creature_package 11 | 1 12 | Package 13 | 14 | 15 | true 16 | 17 | 18 | true 19 | Base 20 | true 21 | 22 | 23 | true 24 | Base 25 | true 26 | 27 | 28 | true 29 | Base 30 | true 31 | 32 | 33 | true 34 | Base 35 | true 36 | 37 | 38 | true 39 | Base 40 | true 41 | 42 | 43 | true 44 | Base 45 | true 46 | 47 | 48 | true 49 | Base 50 | true 51 | 52 | 53 | true 54 | Base 55 | true 56 | 57 | 58 | true 59 | Base 60 | true 61 | 62 | 63 | true 64 | Cfg_1 65 | true 66 | true 67 | 68 | 69 | true 70 | Base 71 | true 72 | 73 | 74 | .\$(Platform)\$(Config) 75 | .\$(Platform)\$(Config) 76 | false 77 | false 78 | false 79 | false 80 | false 81 | true 82 | true 83 | System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) 84 | All 85 | 86 | 87 | None 88 | activity-1.7.2.dex.jar;annotation-experimental-1.4.1.dex.jar;annotation-jvm-1.8.1.dex.jar;annotations-13.0.dex.jar;appcompat-1.2.0.dex.jar;appcompat-resources-1.2.0.dex.jar;billing-7.1.1.dex.jar;biometric-1.1.0.dex.jar;browser-1.4.0.dex.jar;cloud-messaging.dex.jar;collection-jvm-1.4.2.dex.jar;concurrent-futures-1.1.0.dex.jar;core-1.15.0.dex.jar;core-common-2.2.0.dex.jar;core-ktx-1.15.0.dex.jar;core-runtime-2.2.0.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;error_prone_annotations-2.9.0.dex.jar;exifinterface-1.3.6.dex.jar;firebase-annotations-16.2.0.dex.jar;firebase-common-20.3.1.dex.jar;firebase-components-17.1.0.dex.jar;firebase-datatransport-18.1.7.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-encoders-proto-16.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.1.3.dex.jar;firebase-installations-interop-17.1.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-23.1.2.dex.jar;fmx.dex.jar;fragment-1.2.5.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;kotlin-stdlib-1.8.22.dex.jar;kotlin-stdlib-common-1.8.22.dex.jar;kotlin-stdlib-jdk7-1.8.22.dex.jar;kotlin-stdlib-jdk8-1.8.22.dex.jar;kotlinx-coroutines-android-1.6.4.dex.jar;kotlinx-coroutines-core-jvm-1.6.4.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.6.2.dex.jar;lifecycle-livedata-2.6.2.dex.jar;lifecycle-livedata-core-2.6.2.dex.jar;lifecycle-runtime-2.6.2.dex.jar;lifecycle-service-2.6.2.dex.jar;lifecycle-viewmodel-2.6.2.dex.jar;lifecycle-viewmodel-savedstate-2.6.2.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;okio-jvm-3.4.0.dex.jar;play-services-ads-22.2.0.dex.jar;play-services-ads-base-22.2.0.dex.jar;play-services-ads-identifier-18.0.0.dex.jar;play-services-ads-lite-22.2.0.dex.jar;play-services-appset-16.0.1.dex.jar;play-services-base-18.5.0.dex.jar;play-services-basement-18.4.0.dex.jar;play-services-cloud-messaging-17.0.1.dex.jar;play-services-location-21.0.1.dex.jar;play-services-maps-18.1.0.dex.jar;play-services-measurement-base-20.1.2.dex.jar;play-services-measurement-sdk-api-20.1.2.dex.jar;play-services-stats-17.0.2.dex.jar;play-services-tasks-18.2.0.dex.jar;print-1.0.0.dex.jar;profileinstaller-1.3.0.dex.jar;room-common-2.2.5.dex.jar;room-runtime-2.2.5.dex.jar;savedstate-1.2.1.dex.jar;sqlite-2.1.0.dex.jar;sqlite-framework-2.1.0.dex.jar;startup-runtime-1.1.1.dex.jar;tracing-1.2.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.1.8.dex.jar;transport-runtime-3.1.8.dex.jar;user-messaging-platform-2.0.0.dex.jar;vectordrawable-1.1.0.dex.jar;vectordrawable-animated-1.1.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.7.0.dex.jar 89 | rtl;$(DCC_UsePackage) 90 | 91 | 92 | None 93 | activity-1.7.2.dex.jar;annotation-experimental-1.4.1.dex.jar;annotation-jvm-1.8.1.dex.jar;annotations-13.0.dex.jar;appcompat-1.2.0.dex.jar;appcompat-resources-1.2.0.dex.jar;billing-7.1.1.dex.jar;biometric-1.1.0.dex.jar;browser-1.4.0.dex.jar;cloud-messaging.dex.jar;collection-jvm-1.4.2.dex.jar;concurrent-futures-1.1.0.dex.jar;core-1.15.0.dex.jar;core-common-2.2.0.dex.jar;core-ktx-1.15.0.dex.jar;core-runtime-2.2.0.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;error_prone_annotations-2.9.0.dex.jar;exifinterface-1.3.6.dex.jar;firebase-annotations-16.2.0.dex.jar;firebase-common-20.3.1.dex.jar;firebase-components-17.1.0.dex.jar;firebase-datatransport-18.1.7.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-encoders-proto-16.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.1.3.dex.jar;firebase-installations-interop-17.1.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-23.1.2.dex.jar;fmx.dex.jar;fragment-1.2.5.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;kotlin-stdlib-1.8.22.dex.jar;kotlin-stdlib-common-1.8.22.dex.jar;kotlin-stdlib-jdk7-1.8.22.dex.jar;kotlin-stdlib-jdk8-1.8.22.dex.jar;kotlinx-coroutines-android-1.6.4.dex.jar;kotlinx-coroutines-core-jvm-1.6.4.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.6.2.dex.jar;lifecycle-livedata-2.6.2.dex.jar;lifecycle-livedata-core-2.6.2.dex.jar;lifecycle-runtime-2.6.2.dex.jar;lifecycle-service-2.6.2.dex.jar;lifecycle-viewmodel-2.6.2.dex.jar;lifecycle-viewmodel-savedstate-2.6.2.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;okio-jvm-3.4.0.dex.jar;play-services-ads-22.2.0.dex.jar;play-services-ads-base-22.2.0.dex.jar;play-services-ads-identifier-18.0.0.dex.jar;play-services-ads-lite-22.2.0.dex.jar;play-services-appset-16.0.1.dex.jar;play-services-base-18.5.0.dex.jar;play-services-basement-18.4.0.dex.jar;play-services-cloud-messaging-17.0.1.dex.jar;play-services-location-21.0.1.dex.jar;play-services-maps-18.1.0.dex.jar;play-services-measurement-base-20.1.2.dex.jar;play-services-measurement-sdk-api-20.1.2.dex.jar;play-services-stats-17.0.2.dex.jar;play-services-tasks-18.2.0.dex.jar;print-1.0.0.dex.jar;profileinstaller-1.3.0.dex.jar;room-common-2.2.5.dex.jar;room-runtime-2.2.5.dex.jar;savedstate-1.2.1.dex.jar;sqlite-2.1.0.dex.jar;sqlite-framework-2.1.0.dex.jar;startup-runtime-1.1.1.dex.jar;tracing-1.2.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.1.8.dex.jar;transport-runtime-3.1.8.dex.jar;user-messaging-platform-2.0.0.dex.jar;vectordrawable-1.1.0.dex.jar;vectordrawable-animated-1.1.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.7.0.dex.jar 94 | rtl;$(DCC_UsePackage) 95 | 96 | 97 | rtl;$(DCC_UsePackage) 98 | 99 | 100 | rtl;$(DCC_UsePackage) 101 | 102 | 103 | rtl;$(DCC_UsePackage) 104 | 105 | 106 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) 107 | Debug 108 | true 109 | CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= 110 | 1033 111 | rtl;$(DCC_UsePackage) 112 | 113 | 114 | rtl;$(DCC_UsePackage) 115 | 116 | 117 | rtl;$(DCC_UsePackage) 118 | 119 | 120 | DEBUG;$(DCC_Define) 121 | true 122 | false 123 | true 124 | true 125 | true 126 | true 127 | true 128 | 129 | 130 | false 131 | 132 | 133 | false 134 | RELEASE;$(DCC_Define) 135 | 0 136 | 0 137 | 138 | 139 | 140 | MainSource 141 | 142 | 143 | 144 | 145 | Base 146 | 147 | 148 | Cfg_1 149 | Base 150 | 151 | 152 | Cfg_2 153 | Base 154 | 155 | 156 | 157 | Delphi.Personality.12 158 | Package 159 | 160 | 161 | 162 | my_creature_package.dpk 163 | 164 | 165 | 166 | 167 | 168 | true 169 | 170 | 171 | 172 | 173 | true 174 | 175 | 176 | 177 | 178 | true 179 | 180 | 181 | 182 | 183 | my_creature_package.bpl 184 | true 185 | 186 | 187 | 188 | 189 | 1 190 | 191 | 192 | 0 193 | 194 | 195 | 196 | 197 | res\xml 198 | 1 199 | 200 | 201 | res\xml 202 | 1 203 | 204 | 205 | 206 | 207 | library\lib\armeabi 208 | 1 209 | 210 | 211 | library\lib\armeabi 212 | 1 213 | 214 | 215 | 216 | 217 | library\lib\armeabi-v7a 218 | 1 219 | 220 | 221 | 222 | 223 | library\lib\mips 224 | 1 225 | 226 | 227 | library\lib\mips 228 | 1 229 | 230 | 231 | 232 | 233 | library\lib\armeabi-v7a 234 | 1 235 | 236 | 237 | library\lib\arm64-v8a 238 | 1 239 | 240 | 241 | 242 | 243 | library\lib\armeabi-v7a 244 | 1 245 | 246 | 247 | 248 | 249 | res\drawable 250 | 1 251 | 252 | 253 | res\drawable 254 | 1 255 | 256 | 257 | 258 | 259 | res\drawable-anydpi-v21 260 | 1 261 | 262 | 263 | res\drawable-anydpi-v21 264 | 1 265 | 266 | 267 | 268 | 269 | res\values 270 | 1 271 | 272 | 273 | res\values 274 | 1 275 | 276 | 277 | 278 | 279 | res\values-v21 280 | 1 281 | 282 | 283 | res\values-v21 284 | 1 285 | 286 | 287 | 288 | 289 | res\values-v31 290 | 1 291 | 292 | 293 | res\values-v31 294 | 1 295 | 296 | 297 | 298 | 299 | res\values-v35 300 | 1 301 | 302 | 303 | res\values-v35 304 | 1 305 | 306 | 307 | 308 | 309 | res\drawable-anydpi-v26 310 | 1 311 | 312 | 313 | res\drawable-anydpi-v26 314 | 1 315 | 316 | 317 | 318 | 319 | res\drawable 320 | 1 321 | 322 | 323 | res\drawable 324 | 1 325 | 326 | 327 | 328 | 329 | res\drawable 330 | 1 331 | 332 | 333 | res\drawable 334 | 1 335 | 336 | 337 | 338 | 339 | res\drawable 340 | 1 341 | 342 | 343 | res\drawable 344 | 1 345 | 346 | 347 | 348 | 349 | res\drawable-anydpi-v33 350 | 1 351 | 352 | 353 | res\drawable-anydpi-v33 354 | 1 355 | 356 | 357 | 358 | 359 | res\values 360 | 1 361 | 362 | 363 | res\values 364 | 1 365 | 366 | 367 | 368 | 369 | res\values-night-v21 370 | 1 371 | 372 | 373 | res\values-night-v21 374 | 1 375 | 376 | 377 | 378 | 379 | res\drawable 380 | 1 381 | 382 | 383 | res\drawable 384 | 1 385 | 386 | 387 | 388 | 389 | res\drawable-xxhdpi 390 | 1 391 | 392 | 393 | res\drawable-xxhdpi 394 | 1 395 | 396 | 397 | 398 | 399 | res\drawable-xxxhdpi 400 | 1 401 | 402 | 403 | res\drawable-xxxhdpi 404 | 1 405 | 406 | 407 | 408 | 409 | res\drawable-ldpi 410 | 1 411 | 412 | 413 | res\drawable-ldpi 414 | 1 415 | 416 | 417 | 418 | 419 | res\drawable-mdpi 420 | 1 421 | 422 | 423 | res\drawable-mdpi 424 | 1 425 | 426 | 427 | 428 | 429 | res\drawable-hdpi 430 | 1 431 | 432 | 433 | res\drawable-hdpi 434 | 1 435 | 436 | 437 | 438 | 439 | res\drawable-xhdpi 440 | 1 441 | 442 | 443 | res\drawable-xhdpi 444 | 1 445 | 446 | 447 | 448 | 449 | res\drawable-mdpi 450 | 1 451 | 452 | 453 | res\drawable-mdpi 454 | 1 455 | 456 | 457 | 458 | 459 | res\drawable-hdpi 460 | 1 461 | 462 | 463 | res\drawable-hdpi 464 | 1 465 | 466 | 467 | 468 | 469 | res\drawable-xhdpi 470 | 1 471 | 472 | 473 | res\drawable-xhdpi 474 | 1 475 | 476 | 477 | 478 | 479 | res\drawable-xxhdpi 480 | 1 481 | 482 | 483 | res\drawable-xxhdpi 484 | 1 485 | 486 | 487 | 488 | 489 | res\drawable-xxxhdpi 490 | 1 491 | 492 | 493 | res\drawable-xxxhdpi 494 | 1 495 | 496 | 497 | 498 | 499 | res\drawable-small 500 | 1 501 | 502 | 503 | res\drawable-small 504 | 1 505 | 506 | 507 | 508 | 509 | res\drawable-normal 510 | 1 511 | 512 | 513 | res\drawable-normal 514 | 1 515 | 516 | 517 | 518 | 519 | res\drawable-large 520 | 1 521 | 522 | 523 | res\drawable-large 524 | 1 525 | 526 | 527 | 528 | 529 | res\drawable-xlarge 530 | 1 531 | 532 | 533 | res\drawable-xlarge 534 | 1 535 | 536 | 537 | 538 | 539 | res\values 540 | 1 541 | 542 | 543 | res\values 544 | 1 545 | 546 | 547 | 548 | 549 | res\drawable-anydpi-v24 550 | 1 551 | 552 | 553 | res\drawable-anydpi-v24 554 | 1 555 | 556 | 557 | 558 | 559 | res\drawable 560 | 1 561 | 562 | 563 | res\drawable 564 | 1 565 | 566 | 567 | 568 | 569 | res\drawable-night-anydpi-v21 570 | 1 571 | 572 | 573 | res\drawable-night-anydpi-v21 574 | 1 575 | 576 | 577 | 578 | 579 | res\drawable-anydpi-v31 580 | 1 581 | 582 | 583 | res\drawable-anydpi-v31 584 | 1 585 | 586 | 587 | 588 | 589 | res\drawable-night-anydpi-v31 590 | 1 591 | 592 | 593 | res\drawable-night-anydpi-v31 594 | 1 595 | 596 | 597 | 598 | 599 | 1 600 | 601 | 602 | 1 603 | 604 | 605 | 0 606 | 607 | 608 | 609 | 610 | 1 611 | .framework 612 | 613 | 614 | 1 615 | .framework 616 | 617 | 618 | 1 619 | .framework 620 | 621 | 622 | 0 623 | 624 | 625 | 626 | 627 | 1 628 | .dylib 629 | 630 | 631 | 1 632 | .dylib 633 | 634 | 635 | 1 636 | .dylib 637 | 638 | 639 | 0 640 | .dll;.bpl 641 | 642 | 643 | 644 | 645 | 1 646 | .dylib 647 | 648 | 649 | 1 650 | .dylib 651 | 652 | 653 | 1 654 | .dylib 655 | 656 | 657 | 1 658 | .dylib 659 | 660 | 661 | 1 662 | .dylib 663 | 664 | 665 | 1 666 | .dylib 667 | 668 | 669 | 0 670 | .bpl 671 | 672 | 673 | 674 | 675 | 0 676 | 677 | 678 | 0 679 | 680 | 681 | 0 682 | 683 | 684 | 0 685 | 686 | 687 | 0 688 | 689 | 690 | 0 691 | 692 | 693 | 0 694 | 695 | 696 | 0 697 | 698 | 699 | 0 700 | 701 | 702 | 703 | 704 | 1 705 | 706 | 707 | 1 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | Contents\Resources 716 | 1 717 | 718 | 719 | Contents\Resources 720 | 1 721 | 722 | 723 | Contents\Resources 724 | 1 725 | 726 | 727 | 728 | 729 | library\lib\armeabi-v7a 730 | 1 731 | 732 | 733 | library\lib\arm64-v8a 734 | 1 735 | 736 | 737 | 1 738 | 739 | 740 | 1 741 | 742 | 743 | 1 744 | 745 | 746 | 1 747 | 748 | 749 | 1 750 | 751 | 752 | 1 753 | 754 | 755 | 1 756 | 757 | 758 | 0 759 | 760 | 761 | 762 | 763 | library\lib\armeabi-v7a 764 | 1 765 | 766 | 767 | 768 | 769 | 1 770 | 771 | 772 | 1 773 | 774 | 775 | 1 776 | 777 | 778 | 779 | 780 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 781 | 1 782 | 783 | 784 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 785 | 1 786 | 787 | 788 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 789 | 1 790 | 791 | 792 | 793 | 794 | 795 | 796 | 797 | 1 798 | 799 | 800 | 1 801 | 802 | 803 | 1 804 | 805 | 806 | 807 | 808 | Assets 809 | 1 810 | 811 | 812 | Assets 813 | 1 814 | 815 | 816 | 817 | 818 | Assets 819 | 1 820 | 821 | 822 | Assets 823 | 1 824 | 825 | 826 | 827 | 828 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 829 | 1 830 | 831 | 832 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 833 | 1 834 | 835 | 836 | 837 | 838 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 839 | 1 840 | 841 | 842 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 843 | 1 844 | 845 | 846 | 847 | 848 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 849 | 1 850 | 851 | 852 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 853 | 1 854 | 855 | 856 | 857 | 858 | ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset 859 | 1 860 | 861 | 862 | ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset 863 | 1 864 | 865 | 866 | 867 | 868 | ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset 869 | 1 870 | 871 | 872 | ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset 873 | 1 874 | 875 | 876 | 877 | 878 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 879 | 1 880 | 881 | 882 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 883 | 1 884 | 885 | 886 | 887 | 888 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 889 | 1 890 | 891 | 892 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 893 | 1 894 | 895 | 896 | 897 | 898 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 899 | 1 900 | 901 | 902 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 903 | 1 904 | 905 | 906 | 907 | 908 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 909 | 1 910 | 911 | 912 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 913 | 1 914 | 915 | 916 | 917 | 918 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 919 | 1 920 | 921 | 922 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 923 | 1 924 | 925 | 926 | 927 | 928 | ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset 929 | 1 930 | 931 | 932 | ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset 933 | 1 934 | 935 | 936 | 937 | 938 | ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset 939 | 1 940 | 941 | 942 | ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset 943 | 1 944 | 945 | 946 | 947 | 948 | ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset 949 | 1 950 | 951 | 952 | ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset 953 | 1 954 | 955 | 956 | 957 | 958 | ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset 959 | 1 960 | 961 | 962 | ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset 963 | 1 964 | 965 | 966 | 967 | 968 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 969 | 1 970 | 971 | 972 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 973 | 1 974 | 975 | 976 | 977 | 978 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 979 | 1 980 | 981 | 982 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 983 | 1 984 | 985 | 986 | 987 | 988 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 989 | 1 990 | 991 | 992 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 993 | 1 994 | 995 | 996 | 997 | 998 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 999 | 1 1000 | 1001 | 1002 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 1003 | 1 1004 | 1005 | 1006 | 1007 | 1008 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 1009 | 1 1010 | 1011 | 1012 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 1013 | 1 1014 | 1015 | 1016 | 1017 | 1018 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 1019 | 1 1020 | 1021 | 1022 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset 1023 | 1 1024 | 1025 | 1026 | 1027 | 1028 | 1029 | 1030 | 1031 | 1032 | 1033 | 1034 | 1035 | 1036 | 1037 | 1038 | 1039 | 1040 | False 1041 | False 1042 | False 1043 | False 1044 | False 1045 | True 1046 | False 1047 | False 1048 | 1049 | 1050 | 12 1051 | 1052 | 1053 | 1054 | 1055 | 1056 | -------------------------------------------------------------------------------- /200_exceptions/exceptions.dpr: -------------------------------------------------------------------------------- 1 | program exceptions; 2 | 3 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 4 | 5 | uses 6 | SysUtils; 7 | 8 | type 9 | TCreature = class 10 | Name: String; 11 | procedure LoadMyData; 12 | end; 13 | 14 | ECreatureDataError = class(Exception) 15 | AdditionalInformation: String; 16 | SenderCreature: TCreature; 17 | end; 18 | 19 | 20 | (* 21 | // Simplifying, this is Exception class: 22 | type 23 | Exception = class(TObject) 24 | property Message: String read .. .wrote ...; 25 | constructor Create(const AMessage: String); 26 | constructor CreateFmt(const AMessageFormat: String; const Args: array of const); 27 | end; 28 | 29 | constructor Exception.Create(const AMessage: String); 30 | begin 31 | Message := AMessage; 32 | end; 33 | 34 | // Simplifying, this is what Assert does 35 | // (only if $assertions on, otherwise don't even calculate Condition): 36 | procedure Assert(const Condition: Boolean; const Msg: String); 37 | begin 38 | // 39 | if not Condition then 40 | raise EAssertionFailed.Create('Assertion failed' + Msg); 41 | end; 42 | *) 43 | 44 | { TCreature } 45 | 46 | procedure TCreature.LoadMyData; 47 | var 48 | E: ECreatureDataError; 49 | begin 50 | // simple 51 | //raise Exception.Create('Error Message'); 52 | 53 | // also possible with format string 54 | //raise Exception.CreateFmt('Error Message with integer %d', [MyInt]); 55 | 56 | // own exception class with extra info 57 | E := ECreatureDataError.Create('Error in creature data file'); 58 | E.AdditionalInformation := 'Some extra info'; 59 | E.SenderCreature := Self; 60 | raise E; 61 | end; 62 | 63 | var 64 | C: TCreature; 65 | begin 66 | try 67 | try 68 | C := TCreature.Create; 69 | C.Name := 'Werewolf'; 70 | C.LoadMyData; 71 | except 72 | on E: ECreatureDataError do 73 | begin 74 | Writeln(E.ClassName, ': ', E.Message); 75 | Writeln('Additional info: ', E.AdditionalInformation); 76 | Writeln('Creature ', E.SenderCreature.Name); 77 | end; 78 | end; 79 | finally 80 | FreeAndNil(C); 81 | end; 82 | 83 | Readln; 84 | end. 85 | -------------------------------------------------------------------------------- /205_DELIBERATELY_INCORRECT_freeing_memory_garbage/memory_garbage_free.dpr: -------------------------------------------------------------------------------- 1 | program memory_garbage_free; 2 | 3 | { THIS IS WRONG APPLICATION, 4 | ONLY TO SHOW THE PROBLEM WITH FREEING MEMORY GARBAGE. } 5 | 6 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 7 | 8 | uses SysUtils, Generics.Collections; 9 | 10 | procedure Foo; 11 | var 12 | O: TObject; // memory garbage 13 | begin 14 | O := nil; 15 | try 16 | raise Exception.Create('Error Message'); 17 | O := TObject.Create; 18 | Writeln(O.ClassName); 19 | finally 20 | FreeAndNil(O); 21 | end; 22 | end; 23 | 24 | begin 25 | Foo; 26 | Readln; 27 | end. 28 | 29 | -------------------------------------------------------------------------------- /210_exceptions_reraise/reraise.dpr: -------------------------------------------------------------------------------- 1 | program exceptions; 2 | 3 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 4 | 5 | uses SysUtils, Generics.Collections; 6 | 7 | type 8 | TCreature = class 9 | Name: String; 10 | procedure LoadMyData; 11 | end; 12 | 13 | { TCreature } 14 | 15 | procedure TCreature.LoadMyData; 16 | begin 17 | // dummy test, always fail for Werewolf 18 | if Name = 'Werewolf' then 19 | raise Exception.Create('Error Message'); 20 | end; 21 | 22 | procedure LoadData(const Creatures: TObjectList); 23 | var 24 | C: TCreature; 25 | begin 26 | for C in Creatures do 27 | begin 28 | try 29 | C.LoadMyData; 30 | except 31 | on E: Exception do 32 | begin 33 | E.Message := E.Message + ' (on creature ' + C.Name + ')'; 34 | raise; 35 | end; 36 | end; 37 | end; 38 | end; 39 | 40 | var 41 | Creatures: TObjectList; 42 | C: TCreature; 43 | begin 44 | Creatures := TObjectList.Create(true); 45 | try 46 | try 47 | C := TCreature.Create; 48 | C.Name := 'Vampyre'; 49 | Creatures.Add(C); 50 | 51 | C := TCreature.Create; 52 | C.Name := 'Werewolf'; 53 | Creatures.Add(C); 54 | 55 | LoadData(Creatures); 56 | except 57 | on E: Exception do 58 | Writeln(E.ClassName, ': ', E.Message); 59 | end; 60 | finally 61 | FreeAndNil(Creatures); 62 | end; 63 | 64 | Readln; 65 | end. 66 | 67 | -------------------------------------------------------------------------------- /220_exceptions_finally/exceptions_finally.dpr: -------------------------------------------------------------------------------- 1 | program exceptions_finally; 2 | 3 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 4 | 5 | uses 6 | SysUtils; 7 | 8 | type 9 | TCreature = class 10 | Name: String; 11 | HitPoints: Integer; 12 | end; 13 | 14 | function RaiseException: Integer; 15 | begin 16 | raise Exception.Create('No more integers for you'); 17 | end; 18 | 19 | function CreatureFactory: TCreature; 20 | begin 21 | // note: creation outside try guarantees this is correct: 22 | Result := TCreature.Create; 23 | try 24 | Result.Name := 'Werewolf'; 25 | Result.HitPoints := RaiseException; 26 | except 27 | FreeAndNil(Result); 28 | raise; // reraise 29 | end; 30 | 31 | // WRONG! Exception inside try.. now causes free on dangling pointer! 32 | { 33 | try 34 | RaiseException; 35 | Result := TCreature.Create; 36 | Result.Name := 'Werewolf'; 37 | Result.HitPoints := RaiseException; 38 | except 39 | FreeAndNil(Result); 40 | raise; // reraise 41 | end; 42 | } 43 | end; 44 | 45 | var 46 | C: TCreature; 47 | begin 48 | {$ifndef FPC} ReportMemoryLeaksOnShutdown := true; {$endif} 49 | 50 | try 51 | C := CreatureFactory; 52 | except 53 | on E: Exception do 54 | Writeln(E.ClassName, ': ', E.Message); 55 | end; 56 | 57 | Readln; 58 | end. 59 | -------------------------------------------------------------------------------- /225_raise_in_constructor/raise_in_constructor.dpr: -------------------------------------------------------------------------------- 1 | program raise_in_constructor; 2 | 3 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 4 | 5 | uses 6 | SysUtils; 7 | 8 | type 9 | TMyObject = class 10 | MyInt1, MyInt2: Integer; 11 | constructor Create; 12 | destructor Destroy; override; 13 | end; 14 | 15 | { TMyObject } 16 | 17 | constructor TMyObject.Create; 18 | begin 19 | inherited; 20 | MyInt1 := 111; 21 | raise Exception.Create('Error Message'); 22 | MyInt2 := 222; 23 | end; 24 | 25 | destructor TMyObject.Destroy; 26 | begin 27 | Writeln('destruktor ', MyInt1, ' ', MyInt2); 28 | inherited; 29 | end; 30 | 31 | begin 32 | // try 33 | {O := }TMyObject.Create; 34 | // except 35 | // on E: Exception do 36 | // Writeln(E.ClassName, ': ', E.Message); 37 | // end; 38 | 39 | Readln; 40 | end. 41 | -------------------------------------------------------------------------------- /230_classes_inside/classes_inside.dpr: -------------------------------------------------------------------------------- 1 | program classes_inside; 2 | 3 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 4 | 5 | uses 6 | SysUtils; 7 | 8 | type 9 | TCreature = class 10 | Name: String; 11 | procedure Attack; virtual; 12 | end; 13 | 14 | TMyCreatureFactory = class 15 | strict private 16 | type 17 | TVampyre = class(TCreature) 18 | procedure Attack; override; 19 | end; 20 | TWerewolf = class(TCreature) 21 | procedure Attack; override; 22 | end; 23 | var 24 | FMyWerewolf: TWerewolf; 25 | FMyVampyre: TVampyre; 26 | public 27 | constructor Create; 28 | destructor Destroy; override; 29 | function MostFearsome: TCreature; 30 | end; 31 | 32 | { TCreature } 33 | 34 | procedure TCreature.Attack; 35 | begin 36 | Writeln(Name, ' attacks!'); 37 | end; 38 | 39 | { TMyCreatureFactory.TVampyre } 40 | 41 | procedure TMyCreatureFactory.TVampyre.Attack; 42 | begin 43 | Writeln(Name, ' bites!'); 44 | end; 45 | 46 | { TMyCreatureFactory.TWerewolf } 47 | 48 | procedure TMyCreatureFactory.TWerewolf.Attack; 49 | begin 50 | Writeln(Name, ' howls!'); 51 | end; 52 | 53 | { TMyCreatureFactory } 54 | 55 | constructor TMyCreatureFactory.Create; 56 | begin 57 | FMyWerewolf := TWerewolf.Create; 58 | FMyWerewolf.Name := 'Wolfie'; 59 | FMyVampyre := TVampyre.Create; 60 | FMyVampyre.Name := 'Dracula'; 61 | end; 62 | 63 | destructor TMyCreatureFactory.Destroy; 64 | begin 65 | FreeAndNil(FMyWerewolf); 66 | FreeAndNil(FMyVampyre); 67 | inherited; 68 | end; 69 | 70 | function TMyCreatureFactory.MostFearsome: TCreature; 71 | begin 72 | // Return the most fearsome creature 73 | Result := FMyVampyre; 74 | end; 75 | 76 | { Main program } 77 | 78 | var 79 | MyCreatureFactory: TMyCreatureFactory; 80 | begin 81 | try 82 | MyCreatureFactory := TMyCreatureFactory.Create; 83 | try 84 | MyCreatureFactory.MostFearsome.Attack; 85 | finally 86 | FreeAndNil(MyCreatureFactory); 87 | end; 88 | except 89 | on E: Exception do 90 | Writeln(E.ClassName, ': ', E.Message); 91 | end; 92 | 93 | Readln; 94 | end. 95 | -------------------------------------------------------------------------------- /235_class_helpers/class_helpers.dpr: -------------------------------------------------------------------------------- 1 | program class_helpers; 2 | 3 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 4 | 5 | uses SysUtils, MyCreatures; 6 | 7 | type 8 | TWeapon = class 9 | Damage: Integer; 10 | end; 11 | 12 | TCreatureHelper = class helper for TCreature 13 | public 14 | function Alive: Boolean; 15 | procedure Hurt(const Weapon: TWeapon); 16 | end; 17 | 18 | function TCreatureHelper.Alive: Boolean; 19 | begin 20 | Result := HitPoints > 0; 21 | end; 22 | 23 | procedure TCreatureHelper.Hurt(const Weapon: TWeapon); 24 | begin 25 | HitPoints := HitPoints - Weapon.Damage; 26 | end; 27 | 28 | (* 29 | // This would also be reasonable solution. 30 | // Class helpers are just syntactic sugar. 31 | procedure WeaponHurt(const C: TCreature; const Weapon: TWeapon); 32 | begin 33 | C.HitPoints := C.HitPoints - Weapon.Damage; 34 | end; 35 | *) 36 | 37 | var 38 | Sword: TWeapon; 39 | Werewolf: TWerewolf; 40 | begin 41 | try 42 | Sword := TWeapon.Create; 43 | Sword.Damage := 40; 44 | 45 | Werewolf := TWerewolf.Create; 46 | Werewolf.Name := 'Wolfie'; 47 | Werewolf.HitPoints := 100; 48 | 49 | Werewolf.Hurt(Sword); 50 | Writeln(Werewolf.Name, ' has ', Werewolf.HitPoints, ' hit points left, alive: ', Werewolf.Alive); 51 | Werewolf.Hurt(Sword); 52 | Writeln(Werewolf.Name, ' has ', Werewolf.HitPoints, ' hit points left, alive: ', Werewolf.Alive); 53 | Werewolf.Hurt(Sword); 54 | Writeln(Werewolf.Name, ' has ', Werewolf.HitPoints, ' hit points left, alive: ', Werewolf.Alive); 55 | except 56 | on E: Exception do 57 | Writeln(E.ClassName, ': ', E.Message); 58 | end; 59 | 60 | Readln; 61 | end. 62 | 63 | -------------------------------------------------------------------------------- /235_class_helpers/mycreatures.pas: -------------------------------------------------------------------------------- 1 | unit MyCreatures; 2 | 3 | interface 4 | 5 | type 6 | TCreature = class 7 | public 8 | Name: String; 9 | HitPoints: Integer; 10 | end; 11 | 12 | TWerewolf = class(TCreature) 13 | public 14 | end; 15 | 16 | TVampyre = class(TCreature) 17 | public 18 | FangsPoisonous: Boolean; 19 | end; 20 | 21 | implementation 22 | 23 | end. -------------------------------------------------------------------------------- /240_weak_ref/weak_ref.dpr: -------------------------------------------------------------------------------- 1 | program weak_ref; 2 | 3 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 4 | 5 | uses SysUtils, Classes; 6 | 7 | type 8 | TCreature = class(TComponent) 9 | public 10 | Name: String; 11 | procedure Attack; // no need for virtual now 12 | end; 13 | 14 | TMyCreatureManager = class(TComponent) 15 | strict private 16 | FMostFearsome: TCreature; 17 | procedure SetMostFearsome(const Value: TCreature); 18 | protected 19 | procedure Notification(AComponent: TComponent; Operation: TOperation); override; 20 | public 21 | destructor Destroy; override; 22 | property MostFearsome: TCreature read FMostFearsome write SetMostFearsome; 23 | procedure AttackWithMostFearsome; 24 | end; 25 | 26 | { TCreature } 27 | 28 | procedure TCreature.Attack; 29 | begin 30 | Writeln(Name, ' attacks!'); 31 | end; 32 | 33 | { TMyCreatureManager } 34 | 35 | procedure TMyCreatureManager.Notification(AComponent: TComponent; Operation: TOperation); 36 | begin 37 | inherited; 38 | if (Operation = opRemove) and (AComponent = FMostFearsome) then 39 | { set to nil by SetMostFearsome to clean nicely } 40 | MostFearsome := nil; 41 | end; 42 | 43 | procedure TMyCreatureManager.SetMostFearsome(const Value: TCreature); 44 | begin 45 | if FMostFearsome <> Value then 46 | begin 47 | if FMostFearsome <> nil then 48 | FMostFearsome.RemoveFreeNotification(Self); 49 | FMostFearsome := Value; 50 | if FMostFearsome <> nil then 51 | FMostFearsome.FreeNotification(Self); 52 | end; 53 | end; 54 | 55 | destructor TMyCreatureManager.Destroy; 56 | begin 57 | { set to nil by SetMostFearsome, to detach free notification } 58 | MostFearsome := nil; 59 | inherited; 60 | end; 61 | 62 | procedure TMyCreatureManager.AttackWithMostFearsome; 63 | begin 64 | if MostFearsome <> nil then 65 | MostFearsome.Attack 66 | else 67 | Writeln('No creature with which to attack!'); 68 | end; 69 | 70 | { Main program } 71 | 72 | var 73 | MyCreatureManager: TMyCreatureManager; 74 | Werewolf: TCreature; 75 | Vampyre: TCreature; 76 | begin 77 | {$ifndef FPC} ReportMemoryLeaksOnShutdown := true; {$endif} 78 | 79 | try 80 | try 81 | Werewolf := TCreature.Create(nil); 82 | Werewolf.Name := 'Wolfie'; 83 | 84 | Vampyre := TCreature.Create(nil); 85 | Vampyre.Name := 'Dracula'; 86 | 87 | MyCreatureManager := TMyCreatureManager.Create(nil); 88 | MyCreatureManager.MostFearsome := Werewolf; 89 | MyCreatureManager.AttackWithMostFearsome; 90 | 91 | FreeAndNil(Werewolf); 92 | Assert(MyCreatureManager.MostFearsome = nil); 93 | // would crash without FreeNotification 94 | MyCreatureManager.AttackWithMostFearsome; 95 | 96 | MyCreatureManager.MostFearsome := Vampyre; 97 | MyCreatureManager.AttackWithMostFearsome; 98 | finally 99 | FreeAndNil(Werewolf); 100 | FreeAndNil(Vampyre); 101 | FreeAndNil(MyCreatureManager); 102 | end; 103 | except 104 | on E: Exception do 105 | Writeln(E.ClassName, ': ', E.Message); 106 | end; 107 | 108 | Readln; 109 | end. 110 | -------------------------------------------------------------------------------- /250_DELIBERATELY_INCORRECT_weak_ref_trap/weak_ref_trap.dpr: -------------------------------------------------------------------------------- 1 | program weak_ref_trap; 2 | 3 | { THIS EXAMPLE HAS A DELIBERATE, QUITE SUBTLE TO NOTICE, ERROR. 4 | 5 | Run it to see: 6 | 7 | Dracula attacks! 8 | Wolfie tickles! 9 | No creature with which to attack! 10 | Wolfie tickles! 11 | Wolfie attacks! 12 | Wolfie tickles! 13 | No creature with which to attack! 14 | tickles! 15 | 16 | Last line is weird -- looks like Name='' when invoking TickleWithMostFurry 17 | from ThisFails? 18 | Why? 19 | How to fix it? 20 | } 21 | 22 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 23 | 24 | uses 25 | SysUtils, 26 | Classes; 27 | 28 | type 29 | TCreature = class(TComponent) 30 | public 31 | Name: String; 32 | end; 33 | 34 | TMyCreatureManager = class(TComponent) 35 | strict private 36 | FMostFearsome: TCreature; 37 | FMostFurry: TCreature; 38 | procedure SetMostFearsome(const Value: TCreature); 39 | procedure SetMostFurry(const Value: TCreature); 40 | protected 41 | procedure Notification(AComponent: TComponent; Operation: TOperation); override; 42 | public 43 | destructor Destroy; override; 44 | property MostFearsome: TCreature read FMostFearsome write SetMostFearsome; 45 | property MostFurry: TCreature read FMostFurry write SetMostFurry; 46 | procedure AttackWithMostFearsome; 47 | procedure TickleWithMostFurry; 48 | end; 49 | 50 | { TMyCreatureManager } 51 | 52 | procedure TMyCreatureManager.Notification(AComponent: TComponent; Operation: TOperation); 53 | begin 54 | inherited; 55 | if (Operation = opRemove) and (AComponent = FMostFearsome) then 56 | { set to nil by SetMostFearsome to clean nicely } 57 | MostFearsome := nil; 58 | if (Operation = opRemove) and (AComponent = FMostFurry) then 59 | { set to nil by SetMostFurry to clean nicely } 60 | MostFurry := nil; 61 | end; 62 | 63 | procedure TMyCreatureManager.SetMostFearsome(const Value: TCreature); 64 | begin 65 | if FMostFearsome <> Value then 66 | begin 67 | if FMostFearsome <> nil then 68 | FMostFearsome.RemoveFreeNotification(Self); 69 | FMostFearsome := Value; 70 | if FMostFearsome <> nil then 71 | FMostFearsome.FreeNotification(Self); 72 | end; 73 | end; 74 | 75 | procedure TMyCreatureManager.SetMostFurry(const Value: TCreature); 76 | begin 77 | if FMostFurry <> Value then 78 | begin 79 | if FMostFurry <> nil then 80 | FMostFurry.RemoveFreeNotification(Self); 81 | FMostFurry := Value; 82 | if FMostFurry <> nil then 83 | FMostFurry.FreeNotification(Self); 84 | end; 85 | end; 86 | 87 | destructor TMyCreatureManager.Destroy; 88 | begin 89 | { set to nil by SetMostFearsome, to detach free notification } 90 | MostFearsome := nil; 91 | { set to nil by SetMostFurry, to detach free notification } 92 | MostFurry := nil; 93 | inherited; 94 | end; 95 | 96 | procedure TMyCreatureManager.AttackWithMostFearsome; 97 | begin 98 | if MostFearsome <> nil then 99 | Writeln(MostFearsome.Name, ' attacks!') 100 | else 101 | Writeln('No creature with which to attack!'); 102 | end; 103 | 104 | procedure TMyCreatureManager.TickleWithMostFurry; 105 | begin 106 | if MostFurry <> nil then 107 | Writeln(MostFurry.Name, ' tickles!') 108 | else 109 | Writeln('No creature with which to tickle!'); 110 | end; 111 | 112 | { Main program } 113 | 114 | procedure ThisWorks; 115 | var 116 | MyCreatureManager: TMyCreatureManager; 117 | Werewolf: TCreature; 118 | Vampyre: TCreature; 119 | begin 120 | try 121 | Werewolf := TCreature.Create(nil); 122 | Werewolf.Name := 'Wolfie'; 123 | 124 | Vampyre := TCreature.Create(nil); 125 | Vampyre.Name := 'Dracula'; 126 | 127 | MyCreatureManager := TMyCreatureManager.Create(nil); 128 | MyCreatureManager.MostFearsome := Vampyre; 129 | MyCreatureManager.MostFurry := Werewolf; 130 | MyCreatureManager.AttackWithMostFearsome; 131 | MyCreatureManager.TickleWithMostFurry; 132 | 133 | MyCreatureManager.MostFearsome := nil; 134 | 135 | MyCreatureManager.AttackWithMostFearsome; 136 | MyCreatureManager.TickleWithMostFurry; 137 | finally 138 | FreeAndNil(Werewolf); 139 | FreeAndNil(Vampyre); 140 | FreeAndNil(MyCreatureManager); 141 | end; 142 | end; 143 | 144 | procedure ThisFails; 145 | var 146 | MyCreatureManager: TMyCreatureManager; 147 | Werewolf: TCreature; 148 | begin 149 | try 150 | Werewolf := TCreature.Create(nil); 151 | Werewolf.Name := 'Wolfie'; 152 | 153 | MyCreatureManager := TMyCreatureManager.Create(nil); 154 | MyCreatureManager.MostFearsome := Werewolf; 155 | MyCreatureManager.MostFurry := Werewolf; 156 | MyCreatureManager.AttackWithMostFearsome; 157 | MyCreatureManager.TickleWithMostFurry; 158 | 159 | MyCreatureManager.MostFearsome := nil; 160 | FreeAndNil(Werewolf); 161 | 162 | MyCreatureManager.AttackWithMostFearsome; 163 | MyCreatureManager.TickleWithMostFurry; 164 | finally 165 | FreeAndNil(Werewolf); 166 | FreeAndNil(MyCreatureManager); 167 | end; 168 | end; 169 | 170 | begin 171 | {$ifndef FPC} ReportMemoryLeaksOnShutdown := true; {$endif} 172 | 173 | try 174 | ThisWorks; 175 | ThisFails; 176 | except 177 | on E: Exception do 178 | Writeln(E.ClassName, ': ', E.Message); 179 | end; 180 | 181 | Readln; 182 | end. 183 | -------------------------------------------------------------------------------- /260_class_methods_etc/class_methods_etc.dpr: -------------------------------------------------------------------------------- 1 | program class_methods_etc; 2 | 3 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 4 | 5 | uses 6 | SysUtils; 7 | 8 | type 9 | TRocketTarget = (Moon, Mars, Sun); 10 | 11 | TRocket = class 12 | strict private 13 | class var 14 | FTarget: TRocketTarget; 15 | public 16 | // instance stuff 17 | var 18 | Launched: Boolean; 19 | procedure Launch; 20 | 21 | // class stuff 22 | class var 23 | LaunchCount: Cardinal; 24 | LaunchCountPerTarget: array [TRocketTarget] of Cardinal; 25 | class constructor Create; 26 | class destructor Destroy; 27 | // target for all future launches. 28 | class property Target: TRocketTarget read FTarget write FTarget; 29 | end; 30 | 31 | { TRocket } 32 | 33 | class constructor TRocket.Create; 34 | begin 35 | Writeln('Before first usage of TRocket'); 36 | end; 37 | 38 | class destructor TRocket.Destroy; 39 | begin 40 | Writeln('After last usage of TRocket'); 41 | end; 42 | 43 | procedure TRocket.Launch; 44 | begin 45 | if not Launched then 46 | begin 47 | Launched := true; 48 | Inc(LaunchCount); 49 | Inc(LaunchCountPerTarget[FTarget]); 50 | end; 51 | end; 52 | 53 | var 54 | R: TRocket; 55 | begin 56 | try 57 | R := TRocket.Create; try R.Launch; finally FreeAndNil(R); end; 58 | R := TRocket.Create; try R.Launch; finally FreeAndNil(R); end; 59 | R := TRocket.Create; try R.Launch; finally FreeAndNil(R); end; 60 | 61 | TRocket.Target := Mars; 62 | 63 | R := TRocket.Create; try R.Launch; finally FreeAndNil(R); end; 64 | 65 | Writeln('Launched rockets: ', TRocket.LaunchCount); 66 | Writeln(' towards Moon: ', TRocket.LaunchCountPerTarget[Moon]); 67 | Writeln(' towards Mars: ', TRocket.LaunchCountPerTarget[Mars]); 68 | except 69 | on E: Exception do 70 | Writeln(E.ClassName, ': ', E.Message); 71 | end; 72 | 73 | Readln; 74 | end. 75 | -------------------------------------------------------------------------------- /270_class_refs/class_refs.dpr: -------------------------------------------------------------------------------- 1 | program class_refs; 2 | 3 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 4 | 5 | uses SysUtils; 6 | 7 | type 8 | TCreature = class abstract 9 | Name: String; 10 | HitPoints: Integer; 11 | constructor Create; virtual; 12 | class function HasHair: Boolean; virtual; abstract; 13 | end; 14 | 15 | TWerewolf = class(TCreature) 16 | constructor Create; override; 17 | class function HasHair: Boolean; override; 18 | end; 19 | 20 | TVampyre = class(TCreature) 21 | constructor Create; override; 22 | class function HasHair: Boolean; override; 23 | end; 24 | 25 | TRobot = class(TCreature) 26 | constructor Create; override; 27 | class function HasHair: Boolean; override; 28 | end; 29 | 30 | TCreatureClass = class of TCreature; 31 | 32 | { TCreature } 33 | 34 | constructor TCreature.Create; 35 | begin 36 | inherited; 37 | // nothing to do here 38 | end; 39 | 40 | { TWerewolf } 41 | 42 | constructor TWerewolf.Create; 43 | begin 44 | inherited Create; 45 | HitPoints := 100; 46 | case Random(4) of 47 | 0: Name := 'Wolfie'; 48 | 1: Name := 'Fang'; 49 | 2: Name := 'Howler'; 50 | 3: Name := 'Snarler'; 51 | end; 52 | end; 53 | 54 | class function TWerewolf.HasHair: Boolean; 55 | begin 56 | Result := True; 57 | end; 58 | 59 | { TVampyre } 60 | 61 | constructor TVampyre.Create; 62 | begin 63 | inherited Create; 64 | HitPoints := 50; 65 | case Random(4) of 66 | 0: Name := 'Dracula'; 67 | 1: Name := 'Nosferatu'; 68 | 2: Name := 'Count Chocula'; 69 | 3: Name := 'Vlad the Impaler'; 70 | end; 71 | end; 72 | 73 | class function TVampyre.HasHair: Boolean; 74 | begin 75 | Result := True; 76 | end; 77 | 78 | { TRobot } 79 | 80 | constructor TRobot.Create; 81 | begin 82 | inherited Create; 83 | HitPoints := 200; 84 | case Random(4) of 85 | 0: Name := 'R2D2'; 86 | 1: Name := 'C3PO'; 87 | 2: Name := 'Bender'; 88 | 3: Name := 'Optimus Prime'; 89 | end; 90 | end; 91 | 92 | class function TRobot.HasHair: Boolean; 93 | begin 94 | Result := false; 95 | end; 96 | 97 | procedure MakeRandomCreature; 98 | var 99 | MyCreatureClass: TCreatureClass; 100 | C: TCreature; 101 | begin 102 | case Random(3) of 103 | 0: MyCreatureClass := TWerewolf; 104 | 1: MyCreatureClass := TVampyre; 105 | 2: MyCreatureClass := TRobot; 106 | else raise Exception.Create('Should never happen, unexpected Random(3) result'); 107 | end; 108 | 109 | Writeln('Creating a ', MyCreatureClass.ClassName, '...'); 110 | Writeln(' it will have hair? ', MyCreatureClass.HasHair); 111 | 112 | C := MyCreatureClass.Create; 113 | Writeln(' it has name: ', C.Name); 114 | Writeln(' it has hit points: ', C.HitPoints); 115 | FreeAndNil(C); 116 | end; 117 | 118 | begin 119 | try 120 | Randomize; 121 | MakeRandomCreature; 122 | MakeRandomCreature; 123 | MakeRandomCreature; 124 | MakeRandomCreature; 125 | except 126 | on E: Exception do 127 | Writeln(E.ClassName, ': ', E.Message); 128 | end; 129 | 130 | Readln; 131 | end. 132 | -------------------------------------------------------------------------------- /280_generics_simple/MyStringList.pas: -------------------------------------------------------------------------------- 1 | unit MyStringList; 2 | 3 | interface 4 | 5 | uses SysUtils; 6 | 7 | type 8 | { List of strings, each string has a potential associated value of T. } 9 | TMyStringList = class 10 | strict private 11 | type 12 | TOneItem = record 13 | S: String; 14 | HasAssociated: Boolean; 15 | // only meaningful when HasAssociated 16 | Associated: T; 17 | end; 18 | var 19 | FItems: array of TOneItem; 20 | function GetAssociated(const Index: Integer): T; 21 | function GetHasAssociated(const Index: Integer): Boolean; 22 | function GetItems(const Index: Integer): String; 23 | public 24 | procedure Add(const S: String); overload; 25 | procedure Add(const S: String; const Associated: T); overload; 26 | procedure Clear; 27 | function Count: Integer; 28 | property Items[const Index: Integer]: String read GetItems; default; 29 | property HasAssociated[const Index: Integer]: Boolean read GetHasAssociated; 30 | { Read only when HasAssociated[Index]. } 31 | property Associated[const Index: Integer]: T read GetAssociated; 32 | end; 33 | 34 | implementation 35 | 36 | { TMyStringList } 37 | 38 | procedure TMyStringList.Add(const S: String); 39 | var 40 | NewItem: TOneItem; 41 | L: Integer; 42 | begin 43 | NewItem.S := S; 44 | NewItem.Associated := Default(T); 45 | NewItem.HasAssociated := false; 46 | 47 | L := Length(FItems); 48 | SetLength(FItems, L + 1); 49 | FItems[L] := NewItem; 50 | end; 51 | 52 | procedure TMyStringList.Add(const S: String; const Associated: T); 53 | var 54 | NewItem: TOneItem; 55 | L: Integer; 56 | begin 57 | NewItem.S := S; 58 | NewItem.Associated := Associated; 59 | NewItem.HasAssociated := true; 60 | 61 | L := Length(FItems); 62 | SetLength(FItems, L + 1); 63 | FItems[L] := NewItem; 64 | end; 65 | 66 | procedure TMyStringList.Clear; 67 | begin 68 | SetLength(FItems, 0); 69 | end; 70 | 71 | function TMyStringList.Count: Integer; 72 | begin 73 | Result := Length(FItems); 74 | end; 75 | 76 | function TMyStringList.GetAssociated(const Index: Integer): T; 77 | begin 78 | if not FItems[Index].HasAssociated then 79 | raise Exception.Create('No associated value'); 80 | Result := FItems[Index].Associated; 81 | end; 82 | 83 | function TMyStringList.GetHasAssociated(const Index: Integer): Boolean; 84 | begin 85 | Result := FItems[Index].HasAssociated; 86 | end; 87 | 88 | function TMyStringList.GetItems(const Index: Integer): String; 89 | begin 90 | Result := FItems[Index].S; 91 | end; 92 | 93 | end. 94 | -------------------------------------------------------------------------------- /280_generics_simple/generics_simple.dpr: -------------------------------------------------------------------------------- 1 | program generics_simple; 2 | 3 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 4 | 5 | uses 6 | SysUtils, 7 | MyStringList in 'MyStringList.pas'; 8 | 9 | type 10 | TMessageType = (mtError, mrWarning, mtInfo); 11 | const 12 | MsgTypeNames: array [TMessageType] of String = ( 13 | 'error', 14 | 'warning', 15 | 'info' 16 | ); 17 | 18 | var 19 | Messages: TMyStringList; 20 | I: Integer; 21 | begin 22 | try 23 | Messages := TMyStringList.Create; 24 | try 25 | Messages.Add('Sample message'); 26 | Messages.Add('Sample error message', mtError); 27 | Messages.Add('Sample warning message', mrWarning); 28 | Messages.Add('Sample info message', mtInfo); 29 | Writeln('Messages count: ', Messages.Count); 30 | 31 | for I := 0 to Messages.Count - 1 do 32 | begin 33 | Writeln(Messages[I]); 34 | if Messages.HasAssociated[I] then 35 | Writeln(' Associated value: ', 36 | MsgTypeNames[Messages.Associated[I]]); 37 | end; 38 | finally 39 | FreeAndNil(Messages); 40 | end; 41 | except 42 | on E: Exception do 43 | Writeln(E.ClassName, ': ', E.Message); 44 | end; 45 | 46 | Readln; 47 | end. 48 | -------------------------------------------------------------------------------- /285_generic_vectors/generic_vectors.dpr: -------------------------------------------------------------------------------- 1 | program generic_vectors; 2 | 3 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 4 | 5 | type 6 | TVector3 = class 7 | X, Y, Z: T; 8 | end; 9 | 10 | TVector2 = class 11 | X, Y: T; 12 | class function Zero: TVector2; 13 | function To3D(const Z: T): TVector3; 14 | // unfortunately, not possible 15 | //function Add(const Second: TVector2): TVector2; 16 | // unfortunately, not possible 17 | //function Max(const Second: TVector2): TVector2; 18 | end; 19 | 20 | TVector2Integer = TVector2; 21 | TVector2Single = TVector2; 22 | 23 | { TVector2 } 24 | 25 | (* 26 | function TVector2.Max(const Second: TVector2): TVector2; 27 | begin 28 | Result := TVector2.Create; 29 | 30 | if X > Second.X then 31 | Result.X := X 32 | else 33 | Result.X := Second.X; 34 | 35 | if Y > Second.Y then 36 | Result.Y := Y 37 | else 38 | Result.Y := Second.Y; 39 | end; 40 | 41 | function TVector2.Add(const Second: TVector2): TVector2; 42 | begin 43 | Result := TVector2.Create; 44 | Result.X := X + Second.X; 45 | Result.Y := Y + Second.Y; 46 | end; 47 | *) 48 | 49 | function TVector2.To3D(const Z: T): TVector3; 50 | begin 51 | Result := TVector3.Create; 52 | Result.X := X; // field 53 | Result.Y := Y; // field 54 | Result.Z := Z; // argument 55 | end; 56 | 57 | class function TVector2.Zero: TVector2; 58 | begin 59 | Result := TVector2.Create; 60 | Result.X := Default(T); 61 | Result.Y := Default(T); 62 | end; 63 | 64 | begin 65 | end. 66 | -------------------------------------------------------------------------------- /287_generic_lists_usage/generic_lists.dpr: -------------------------------------------------------------------------------- 1 | program generic_lists; 2 | 3 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 4 | 5 | uses SysUtils, Generics.Collections; 6 | 7 | type 8 | TCreature = class 9 | HitPoints: Integer; 10 | end; 11 | var 12 | Creaturess: TObjectList; 13 | I: Integer; 14 | begin 15 | Creaturess := TObjectList.Create(true); 16 | 17 | Creaturess.Add(TCreature.Create); 18 | Creaturess.Add(TCreature.Create); 19 | Creaturess.Add(TCreature.Create); 20 | //Creaturess.Add(TObject.Create); // impossible to compile 21 | 22 | for I := 0 to Creaturess.Count - 1 do 23 | begin 24 | Creaturess[I].HitPoints := Creaturess[I].HitPoints + 100; 25 | // not need for typecasts 26 | end; 27 | 28 | FreeAndNil(Creaturess); 29 | 30 | Readln; 31 | end. 32 | -------------------------------------------------------------------------------- /290_generics_2d_grid/MyGrid2D.pas: -------------------------------------------------------------------------------- 1 | unit MyGrid2D; 2 | 3 | interface 4 | 5 | uses SysUtils; 6 | 7 | type 8 | TGrid2D = class 9 | strict private 10 | type 11 | TOneItem = record 12 | IsValue: Boolean; 13 | Value: T; 14 | end; 15 | var 16 | FItems: array of array of TOneItem; 17 | FWidth, FHeight: Integer; 18 | private 19 | function GetHasItems(const X, Y: Integer): Boolean; 20 | function GetItems(const X, Y: Integer): T; 21 | //procedure SetHasItems(const X, Y: Integer; const Value: Boolean); 22 | procedure SetItems(const X, Y: Integer; const Value: T); 23 | public 24 | constructor Create(const AWidth, AHeight: Cardinal); 25 | property Width: Integer read FWidth; 26 | property Height: Integer read FHeight; 27 | property Items[const X, Y: Integer]: T 28 | read GetItems write SetItems; default; 29 | property HasItems[const X, Y: Integer]: Boolean 30 | read GetHasItems; 31 | procedure ClearItem(const X, Y: Integer); 32 | end; 33 | 34 | implementation 35 | 36 | 37 | { TGrid2D } 38 | 39 | procedure TGrid2D.ClearItem(const X, Y: Integer); 40 | begin 41 | 42 | end; 43 | 44 | constructor TGrid2D.Create(const AWidth, AHeight: Cardinal); 45 | begin 46 | inherited Create; 47 | FWidth := AWidth; 48 | FHeight := AHeight; 49 | SetLength(FItems, AWidth, AHeight); 50 | end; 51 | 52 | function TGrid2D.GetHasItems(const X, Y: Integer): Boolean; 53 | begin 54 | Result := FItems[X, Y].IsValue; 55 | end; 56 | 57 | function TGrid2D.GetItems(const X, Y: Integer): T; 58 | begin 59 | if not HasItems[X, Y] then 60 | raise Exception.CreateFmt('No item at %d, %d', [X, Y]); 61 | 62 | Result := FItems[X, Y].Value; 63 | end; 64 | 65 | // Unused -- better to set using ClearItem (to false) or during SetItems (to true). 66 | // procedure TGrid2D.SetHasItems(const X, Y: Integer; const Value: Boolean); 67 | // begin 68 | // FItems[X, Y].IsValue := false; 69 | // end; 70 | 71 | procedure TGrid2D.SetItems(const X, Y: Integer; const Value: T); 72 | begin 73 | FItems[X, Y].IsValue := true; 74 | FItems[X, Y].Value := Value; 75 | end; 76 | 77 | end. 78 | -------------------------------------------------------------------------------- /290_generics_2d_grid/generics_2d_grid.dpr: -------------------------------------------------------------------------------- 1 | program generics_2d_grid; 2 | 3 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 4 | 5 | uses 6 | SysUtils, 7 | MyGrid2D in 'MyGrid2D.pas'; 8 | 9 | type 10 | TChessPieceType = (Rook, Knight, Bishop, King, Queen, Pawn); 11 | TChessPiece = record 12 | PieceType: TChessPieceType; 13 | IsWhite: Boolean; 14 | end; 15 | TChessBoard = TGrid2D; 16 | 17 | TCheckersPiece = Boolean; // is white 18 | TCheckersBoard = TGrid2D; 19 | 20 | TShip = (ShipHit, ShipHealthy); 21 | TShips = TGrid2D; 22 | 23 | const 24 | ChessPieceChar: array [TChessPieceType] of Char = 25 | ('R', 'k', 'B', 'K', 'Q', 'P'); 26 | 27 | function ChessPiece(const PieceType: TChessPieceType; 28 | const IsWhite: Boolean): TChessPiece; 29 | begin 30 | Result.PieceType := PieceType; 31 | Result.IsWhite := IsWhite; 32 | end; 33 | 34 | var 35 | ChessBoard: TChessBoard; 36 | X, Y: Integer; 37 | begin 38 | try 39 | ChessBoard := TChessBoard.Create(8, 8); 40 | try 41 | ChessBoard[0, 0] := ChessPiece(Rook, true); 42 | ChessBoard[1, 0] := ChessPiece(Knight, true); 43 | ChessBoard[2, 0] := ChessPiece(Bishop, true); 44 | ChessBoard[0, 7] := ChessPiece(Rook, false); 45 | ChessBoard[1, 7] := ChessPiece(Knight, false); 46 | ChessBoard[2, 7] := ChessPiece(Bishop, false); 47 | for Y := 0 to ChessBoard.Height - 1 do 48 | begin 49 | for X := 0 to ChessBoard.Width - 1 do 50 | begin 51 | if ChessBoard.HasItems[X, Y] then 52 | begin 53 | Write(ChessPieceChar[ChessBoard.Items[X, Y].PieceType]); 54 | if ChessBoard.Items[X, Y].IsWhite then 55 | Write('_') 56 | else 57 | Write('^'); 58 | end else 59 | Write(' '); 60 | end; 61 | Writeln; 62 | end; 63 | finally 64 | FreeAndNil(ChessBoard); 65 | end; 66 | except 67 | on E: Exception do 68 | Writeln(E.ClassName, ': ', E.Message); 69 | end; 70 | 71 | Readln; 72 | end. 73 | -------------------------------------------------------------------------------- /300_callbacks_events/callbacks_events.dpr: -------------------------------------------------------------------------------- 1 | program callbacks_events; 2 | 3 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 4 | 5 | uses 6 | SysUtils; 7 | 8 | type 9 | TMyFunction = function (const X, Y: Integer): Integer; 10 | 11 | TMyEvent = function (const X, Y: Integer): Integer of object; 12 | 13 | TMyReference = reference to function (const X, Y: Integer): Integer; 14 | 15 | TMyClass = class 16 | function Add(const X, Y: Integer): Integer; 17 | function Multiply(const X, Y: Integer): Integer; 18 | end; 19 | 20 | { TMyClass } 21 | 22 | function TMyClass.Add(const X, Y: Integer): Integer; 23 | begin 24 | Result := X + Y; 25 | end; 26 | 27 | function TMyClass.Multiply(const X, Y: Integer): Integer; 28 | begin 29 | Result := X * Y; 30 | end; 31 | 32 | { Compare methods comparing both instance and code pointer. } 33 | function SameMethods(const AMethod1, AMethod2: TMethod): Boolean; 34 | begin 35 | Result := 36 | (AMethod1.Code = AMethod2.Code) and 37 | (AMethod1.Data = AMethod2.Data); 38 | end; 39 | 40 | function AddGlobal(const X, Y: Integer): Integer; 41 | begin 42 | Result := X + Y; 43 | end; 44 | 45 | var 46 | C1, C2: TMyClass; 47 | E1, E2: TMyEvent; 48 | R: TMyReference; 49 | begin 50 | try 51 | try 52 | C1 := TMyClass.Create; 53 | C2 := TMyClass.Create; 54 | 55 | E1 := C1.Add; 56 | E2 := C1.Multiply; 57 | Writeln('C1.Add = C1.Multiply? ', @E1 = @E2); 58 | Writeln('C1.Add = C1.Multiply, using SameMethods? ', SameMethods(TMethod(E1), TMethod(E2))); 59 | 60 | Writeln(E1(12, 34)); 61 | Writeln(E2(12, 34)); 62 | 63 | E1 := C1.Add; 64 | E2 := C2.Add; 65 | Writeln('C1.Add = C2.Add? ', @E1 = @E2); 66 | Writeln('C1.Add = C2.Add, using SameMethods? ', SameMethods(TMethod(E1), TMethod(E2))); 67 | 68 | R := C1.Add; 69 | Writeln(R(123, 567)); 70 | R := AddGlobal; 71 | Writeln(R(123, 567)); 72 | finally 73 | FreeAndNil(C1); 74 | FreeAndNil(C2); 75 | end; 76 | except 77 | on E: Exception do 78 | Writeln(E.ClassName, ': ', E.Message); 79 | end; 80 | 81 | Readln; 82 | end. 83 | -------------------------------------------------------------------------------- /305_callbacks_assigning/func_callbacks.dpr: -------------------------------------------------------------------------------- 1 | program func_callbacks; 2 | 3 | uses SysUtils; 4 | 5 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 6 | 7 | type 8 | TMyFunction = function(const X, Y: Integer): Integer; 9 | // SizeOf(Pointer) 10 | 11 | TMyEvent = function(const X, Y: Integer): Integer of object; 12 | // 2 * SizeOf(Pointer); 13 | 14 | TMyReference = reference to function(const X, Y: Integer): Integer; 15 | 16 | function Add(const X, Y: Integer): Integer; 17 | begin 18 | Result := X + Y; 19 | end; 20 | 21 | function Multiple(const X, Y: Integer): Integer; 22 | begin 23 | Result := X * Y; 24 | end; 25 | 26 | type 27 | TMyCalculator = class 28 | Name: String; 29 | function Add(const X, Y: Integer): Integer; 30 | function Multiple(const X, Y: Integer): Integer; 31 | end; 32 | 33 | function TMyCalculator.Add(const X, Y: Integer): Integer; 34 | begin 35 | Writeln('my calculator with name ', Name); 36 | Result := X + Y; 37 | end; 38 | 39 | function TMyCalculator.Multiple(const X, Y: Integer): Integer; 40 | begin 41 | Result := X * Y; 42 | end; 43 | 44 | var 45 | F: TMyReference; 46 | X, Y: Integer; 47 | C: Char; 48 | MC: TMyCalculator; 49 | begin 50 | MC := TMyCalculator.Create; 51 | try 52 | MC.Name := 'Good Calculator'; 53 | 54 | Writeln('give X'); 55 | Readln(X); 56 | 57 | Writeln('give Y'); 58 | Readln(Y); 59 | 60 | Writeln('give operation (+, *)'); 61 | Readln(C); 62 | case C of 63 | '+': F := MC.Add; // Add 64 | '*': F := MC.Multiple; 65 | else raise Exception.Create('Invalid input'); 66 | end; 67 | 68 | Writeln(F(X, Y)); 69 | finally 70 | FreeAndNil(MC); 71 | end; 72 | 73 | Readln; 74 | end. 75 | -------------------------------------------------------------------------------- /310_anonymous/anonymous.dpr: -------------------------------------------------------------------------------- 1 | { Example of Map, ForEach methods and processing list with anonymous functions. 2 | Adjusted from https://castle-engine.io/modern_pascal . } 3 | 4 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 5 | 6 | uses SysUtils, Generics.Collections; 7 | 8 | type 9 | TIntMapFunc = 10 | reference to function(const Index, Item: Integer): Integer; 11 | TIntMapProc = 12 | reference to procedure(const Index, Item: Integer); 13 | 14 | TMyInts = class(TList) 15 | { Change every item in the list using AFunc. } 16 | procedure Map(const AFunc: TIntMapFunc); 17 | { Call AProc for every item in the list. } 18 | procedure ForEach(const AProc: TIntMapProc); 19 | end; 20 | 21 | procedure TMyInts.Map(const AFunc: TIntMapFunc); 22 | var 23 | Index: Integer; 24 | begin 25 | for Index := 0 to Count - 1 do 26 | Items[Index] := AFunc(Index, Items[Index]); 27 | end; 28 | 29 | procedure TMyInts.ForEach(const AProc: TIntMapProc); 30 | var 31 | Index: Integer; 32 | begin 33 | for Index := 0 to Count - 1 do 34 | AProc(Index, Items[Index]); 35 | end; 36 | 37 | var 38 | MyList: TMyInts; 39 | I: Integer; 40 | F: TIntMapFunc; 41 | begin 42 | MyList := TMyInts.Create; 43 | try 44 | for I := 0 to 10 do 45 | MyList.Add(I); 46 | 47 | F := function(const Index, Item: Integer): Integer 48 | begin 49 | Result := Item + 1; 50 | end; 51 | // effectively this increases all numbers on the list by 3 52 | MyList.Map(F); 53 | MyList.Map(F); 54 | MyList.Map(F); 55 | 56 | // change all items to their squares 57 | MyList.Map(function(const Index, Item: Integer): Integer 58 | begin 59 | Result := Item * Item; 60 | end); 61 | 62 | // print all items 63 | MyList.ForEach(procedure(const Index, Item: Integer) 64 | begin 65 | WriteLn('Index: ', Index, ', Item: ', Item); 66 | WriteLn(' If we would proces it by F: ', F(Index, Item)); 67 | end); 68 | finally FreeAndNil(MyList) end; 69 | 70 | Readln; 71 | end. 72 | -------------------------------------------------------------------------------- /400_advanced_records_initialize/adv_rec.dpr: -------------------------------------------------------------------------------- 1 | program adv_rec; 2 | 3 | {$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif} 4 | 5 | type 6 | TVector3 = record 7 | function Len: Single; 8 | class operator Initialize({$ifdef FPC}var{$else}out{$endif} V: TVector3); 9 | class operator Finalize(var V: TVector3); 10 | case Integer of 11 | 0: (X, Y, Z: Single); 12 | 1: (Data: array [0..2] of Single); 13 | end; 14 | 15 | var 16 | VectorsNum: Cardinal; 17 | 18 | class operator TVector3.Initialize({$ifdef FPC}var{$else}out{$endif} V: TVector3); 19 | begin 20 | Inc(VectorsNum); 21 | Writeln('TVector3.Initialize, now count: ', VectorsNum); 22 | end; 23 | 24 | class operator TVector3.Finalize(var V: TVector3); 25 | begin 26 | Dec(VectorsNum); 27 | Writeln('TVector3.Finalize, now count: ', VectorsNum); 28 | end; 29 | 30 | function TVector3.Len: Single; 31 | begin 32 | Result := Sqrt(Sqr(X) + Sqr(Y) + Sqr(Z)); 33 | end; 34 | 35 | procedure Foo; 36 | var 37 | V: TVector3; 38 | VA: array [0..9] of TVector3; 39 | begin 40 | { We need to *use* the V and VA, otherwise optimizer (FPC 3.3.1) 41 | could detect they are unused and not call TVector3.Initialize, 42 | TVector3.Finalize. } 43 | V.X := 1.23; 44 | VA[0].X := 4.56; 45 | end; 46 | 47 | begin 48 | Foo; 49 | Readln; 50 | end. 51 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2025, Michalis Kamburelis 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # FPC command line options. 2 | # See README.md for justification of using Delphi mode (-Mdelphi). 3 | FPC_COMMAND:=fpc -Mdelphi 4 | 5 | # Delphi (dcc) command line options. 6 | # See https://github.com/castle-engine/castle-engine/blob/master/tools/build-tool/code/toolcompile.pas#L858 7 | # for how Castle Game Engine build tool invokes dcc for some hints. 8 | # -NS below follows the DPROJ settings generated by Delphi for new projects. 9 | DELPHI_OPTIONS_COMMON:='-NSSystem;Xml;Data;Datasnap;Web;Soap' 10 | DELPHI_WIN32_COMMAND:=dcc32 $(DELPHI_OPTIONS_COMMON) 11 | DELPHI_WIN64_COMMAND:=dcc64 $(DELPHI_OPTIONS_COMMON) 12 | 13 | # Compile all examples with FPC. 14 | # Use `find` to find all *.dpr files (including subdirectories) 15 | # and compile them with FPC, in Delphi mode (-Mdelphi, 16 | # see README.md for explanation why we use Delphi mode). 17 | .PHONY: all 18 | all: 19 | find . \ 20 | '(' -type d -name '140_forms_etc' -prune ')' -o \ 21 | '(' -type d -name '150_data_module_using_components' -prune ')' -o \ 22 | '(' -type d -name '310_anonymous' -prune ')' -o \ 23 | '(' -type d -name '305_callbacks_assigning' -prune ')' -o \ 24 | '(' -type d -name '300_callbacks_events' -prune ')' -o \ 25 | '(' -type f -iname *.dpr \ 26 | '(' -execdir $(FPC_COMMAND) {} ';' -o -quit ')' \ 27 | ')' 28 | 29 | # If you have FPC 3.3.1, you can use this, to test more examples. 30 | .PHONY: all-fpc331 31 | all-fpc331: 32 | find . \ 33 | '(' -type d -name '140_forms_etc' -prune ')' -o \ 34 | '(' -type d -name '150_data_module_using_components' -prune ')' -o \ 35 | '(' -type f -iname *.dpr \ 36 | '(' -execdir $(FPC_COMMAND) {} ';' -o -quit ')' \ 37 | ')' 38 | 39 | # Build with Delphi for Win32. 40 | .PHONY: all-delphi-win32 41 | all-delphi-win32: 42 | find . \ 43 | '(' -type f -iname *.dpr \ 44 | '(' -execdir $(DELPHI_WIN32_COMMAND) {} ';' -o -quit ')' \ 45 | ')' 46 | 47 | # Build with Delphi for Win64. 48 | .PHONY: all-delphi-win64 49 | all-delphi-win64: 50 | find . \ 51 | '(' -type f -iname *.dpr \ 52 | '(' -execdir $(DELPHI_WIN64_COMMAND) {} ';' -o -quit ')' \ 53 | ')' 54 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Examples for the course about modern Object Pascal 2 | 3 | ## BSC course information 4 | 5 | These examples have been prepared to explain Pascal language features during the course organized by [BSC](https://www.bsc.com.pl/) and directed at Delphi developers. 6 | 7 | The course, and these examples, has been taught by _Michalis Kamburelis_, author of [Modern Object Pascal Introduction for Programmers](https://castle-engine.io/modern_pascal) and [Castle Game Engine](https://castle-engine.io/). 8 | 9 | [Course information is here](https://www.bsc.com.pl/szkolenie-nowoczesny-obiektowy-pascal/). It happened, online, on 2025-04-09 and 2025-04-10. If you're interested in attending the next edition or similar courses, [let BSC know](https://www.bsc.com.pl/about/kontakt/). 10 | 11 | ## Examples 12 | 13 | This repository contains the examples used during the course. 14 | 15 | **Compatibility**: Almost all the examples should compile with: 16 | 17 | - either Delphi or FPC compilers (we tested Delphi 12, FPC 3.2.2, FPC 3.3.1 from 2025-03-02), 18 | 19 | - any operating system (we tested Windows and Linux). 20 | 21 | The exceptions are 22 | 23 | - Examples in `140_forms_etc` and `150_data_module_using_components`, which will compile only with Delphi, as they depend on FMX / VCL. 24 | 25 | - Examples in `310_anonymous`, `305_callbacks_assigning`, `300_callbacks_events` which show anonymous functions and function references. They will compile only in Delphi or FPC >= 3.3.1. Older FPC 3.2.2 didn't have anonymous functions and function references implemented. 26 | 27 | Note: Most of the examples show the correct, recommended way of doing something. They should work correctly and exhibit no memory leaks. The exceptions are examples marked with `DELIBERATELY_INCORRECT` in the directory name -- these are knowingly incorrect for some reason, to illustate something. 28 | 29 | Note: We chose to use FPC "Delphi mode" for these examples, to have the simplest code that compiles with both Delphi and FPC. An alternative would be to use FPC "ObjFpc mode", which in our opinion brings some benefits over "Delphi mode" (e.g. `@` for callbacks has more sane behavior), but also more incompatibilities with Delphi (which would need to be addressed by adding `{$ifdef FPC}` or `{$ifdef FPC_OBJFPC}` around the code). 30 | 31 | ## Slides 32 | 33 | Slides from the course: 34 | 35 | - Day 1: https://castle-engine.io/bsc_pascal_1 36 | - Day 2: https://castle-engine.io/bsc_pascal_2 37 | 38 | The slides are in Polish. In the future we may prepare translated English version as well. -------------------------------------------------------------------------------- /github_orgazation_metadata/modern_pascal_organization_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/modern-pascal/modern-pascal-course/c82a559683cd0fa4a7666d7b0beb324d645d2cfb/github_orgazation_metadata/modern_pascal_organization_icon.png -------------------------------------------------------------------------------- /github_orgazation_metadata/modern_pascal_organization_icon.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/modern-pascal/modern-pascal-course/c82a559683cd0fa4a7666d7b0beb324d645d2cfb/github_orgazation_metadata/modern_pascal_organization_icon.xcf --------------------------------------------------------------------------------