├── .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
--------------------------------------------------------------------------------