Mike Torrettinni
Members-
Content Count
1509 -
Joined
-
Last visited
-
Days Won
3
Everything posted by Mike Torrettinni
-
Overload methods or use unique names?
Mike Torrettinni replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
I think my examples were not clear enough how complicated it gets when you add additional info, like TaskName, TaskPath, RunLevel, QueueID.... parameters that define each TTaskAction. So, for this case, I renamed all methods. -
Overload methods or use unique names?
Mike Torrettinni replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
This is odd... the TTaskAction controls the behavior of each Task/how task is executed... for example: RunTasks method executes each task based on TTaskAction value. You are saying that all logic related to task should check all values (parameters in AddTask) and then decide the execution? Probably I don't understand what you mean, because this makes no sense to me, that would be a big mess of IFs. -
How to manage defined list values
Mike Torrettinni posted a topic in Algorithms, Data Structures and Class Design
Not sure how to frame the question title, so I hope it makes sense what I'm trying to ask: I have many examples of defined values and I use one of the 2 approaches below. Is there a better approach, or it is what it is: For example: I have Projects that are defined with 3 values: enum, internal_id (default value from external data) and caption (to show user). So, here is 1st approach that I use: type TProjectType = (ptMain, ptSub, ptExternalDev, ptInternalDev); const cProjDefValues: array[TProjectType] of string = ('main_proj', 'sub_proj', 'dev_ext', 'dev_int'); cProjCaptions: array[TProjectType] of string = ('Main Project', 'Sub Project', 'External Dev Project', 'Internal Dev Project'); And then I just use TProjectType to retrieve DefValue or Caption, whatever I need from consts. I like this approach, but the problem is for example where I have 20+ enums - in this case the code because a long messy, not quickly readable, since each has to have 20+ values. And here is another example that I sometimes use, 2nd example: type TProjectType = (ptMain, ptSub, ptExternalDev, ptInternalDev); TProject = record ProjectType: TProjectType; DefValue: string; Caption: string; constructor New(const aType: TProjectType; const aDefValue, aCaption: string); end; Projects: TList<TProject>; constructor TProject.New(const aType: TProjectType; const aDefValue: string; const aCaption: string); begin ProjectType := aType; DefValue := aDefValue; Caption := aCaption; end; procedure TForm7.FormCreate(Sender: TObject); begin Projects := TList<TProject>.Create; Projects.Add(TProject.New(ptMain, 'main_proj', 'Project')); Projects.Add(TProject.New(ptSub, 'sub_proj', 'Sub Project')); Projects.Add(TProject.New(ptExternalDev, 'dev_ext', 'External Dev Project')); Projects.Add(TProject.New(ptInternalDev, 'dev_int', 'Internal Dev Project')); end; I like this approach, because I have all definitions in single method, even if I have 100+ records, it's still in 1 method. But I need to run this method at the start, while 1st example just exists, without creating any data. So, what I'm looking for is any kind of comment, advice what is better, is there a third way (even better than these example). -
How to manage defined list values
Mike Torrettinni replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
Thank you, interesting idea, especially if they have very similar or even same structure. -
How to manage defined list values
Mike Torrettinni replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
OK, it makes sense. I'm trying to find easiest solution to manage, but it's hard when in the middle of the progress I find out about different or better approach. -
How to manage defined list values
Mike Torrettinni replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
Last question before I do some testing with new approaches: Would you reconsider your chosen approach if you have 100+ type of enums? If you have so much different data, that you need to repeat your implementation for 100+ times... would it make sense to still use your approach, or in such case you would (or have you) use something else? -
How to manage defined list values
Mike Torrettinni replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
Aha, I see. InitHelper initializes Caption, right? From const of names.., OR is Caption a function that return const_of_names[ptExternalDev]? -
How to manage defined list values
Mike Torrettinni replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
So, you use record helpers instead of: cProjCaptions[ptMain] ? -
How to manage defined list values
Mike Torrettinni replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
Are you talking about TCustomAttribute, like this answer: https://stackoverflow.com/questions/2134120/delphi-2010-rtti-explore-enumerations/2620883#2620883 -
How to manage defined list values
Mike Torrettinni replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
Wow, so many different implementations, I had a problem choosing between the 2 I knew of 🙂 -
Deal - breaker: Registration Limit Increase
Mike Torrettinni replied to John Kouraklis's topic in General Help
Aha, I see. I thought he meant that Delphi could detect Delphi running in other VMs and it could affect (prevent?) registration... that would be pretty interesting. -
Deal - breaker: Registration Limit Increase
Mike Torrettinni replied to John Kouraklis's topic in General Help
Why? Issues with Delphi? Does Delphi detect multiple VMs running and gives problems with registration? -
For debugging purpose I'm thinking of creating a simple parses that will parse method arguments and create simple Log call function. Something like this: The parser would have simple form with Memo control, that I would copy paste a method definition into it, for example: procedure MethodA(const Param1: string; var Param2, Param3: integer; Param4: string); And parser would parse method name and parameters and based on the type create Log line: LogMethod('MethodA', 'Str: Param1 = ' + Param1 + ' Int: Param2 = ' + Param2.toString + ' Int: Param3 = ' + Param3.toString + ' Str: Param4 = ' + Param4); And LogMethod makes simple output of the line. I would just add this log line into first line in the MethodA. The purpose is that I can enable logging parameters with a simple copy paste, and no need to manually create LogMethod calls. Is there anything like similar already available?
-
Parse and Log method parameters
Mike Torrettinni replied to Mike Torrettinni's topic in RTL and Delphi Object Pascal
Thanks for suggestions, will see what I can come up with. -
Parse and Log method parameters
Mike Torrettinni replied to Mike Torrettinni's topic in RTL and Delphi Object Pascal
Great, thanks! I assume this doesn't work for array parameters or custom types, like: Param1: array of string; or Param1: TCustomType; or Param1: TArray<TCustomType>; -
Parse and Log method parameters
Mike Torrettinni replied to Mike Torrettinni's topic in RTL and Delphi Object Pascal
Aha, I never used array of const, yet. -
Parse and Log method parameters
Mike Torrettinni replied to Mike Torrettinni's topic in RTL and Delphi Object Pascal
I'm not sure what you have in mind... if I have methods with parameters like: (string, string, integer) (integer, integer, integer, string) .... and all other options of number and type of parameters. -
Parse and Log method parameters
Mike Torrettinni replied to Mike Torrettinni's topic in RTL and Delphi Object Pascal
OK, if I skip the names, what would the LogMethod parameter type be to accept [par1, par2, par3]? array of what? They can be different types. -
Parse and Log method parameters
Mike Torrettinni replied to Mike Torrettinni's topic in RTL and Delphi Object Pascal
Yes, parser needs to identify the type and convert to string as needed, either with .toString or by custom methods VarToStr... it will have to deal with custom types, too. and if you have functions to convert every type to string, then is just a matter of calling correct conversion. -
TArray vs TList with VirtualStringTree
Mike Torrettinni posted a topic in Algorithms, Data Structures and Class Design
Usually I use TArray data with VirtualStringTree, but now I started testing with TList and I got to the little issue - see the error in this simple example: // copied from VirtualTrees TVirtualNode = packed record end; PVirtualNode = ^TVirtualNode; // my record used in TArray, and now in TList TRecLine = record VirtualNode: PVirtualNode; end; procedure TForm1.FormCreate(Sender: TObject); var vArray: TArray<TRecLine>; vList: TList<TRecLine>; vNode: PVirtualNode; begin // just simple code to test cmopile error vArray[0].VirtualNode := vNode; vList[0].VirtualNode := vNode; // <- [dcc32 Error] Unit1.pas(41): E2064 Left side cannot be assigned to end; Why it complains here? I thought TArray and TList are quite similar containers... what can I do here? The rest of the code works pretty well, replacing TArray with TList. Thanks! -
TArray vs TList with VirtualStringTree
Mike Torrettinni replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
5 months later I had to come back to this to understand how to use direct access to record in TList<T>. Thanks again! -
Rules for changing cursor to HourGlass and back
Mike Torrettinni posted a topic in Tips / Blogs / Tutorials / Videos
My projects sometimes work with large files, read, parse, write, export to csv, process... sometimes action can take a few seconds, so I like to change the cursor to crHourGlass at the beginning and then back to crDefault. While refactoring, I had occasions when I created common methods that had the change of cursor while processing. The problem is when I use button to call this method, and I already change cursor in buttons' OnClick. So, a mess. Now I have a rule only to change cursor in control handlers, not in any methods, anymore. This is working good, so far. I have 2 methods that I use instead of remembering exact syntax: procedure SetCursorBegin(Cursor: TCursor = crHourGlass); begin Screen.Cursor := Cursor; end; procedure SetCursorEnd; begin Screen.Cursor := crDefault; end; I only develop for Windows. I was just wondering if anybody has different experience and has any good tips on how to deal with cursor changing, or maybe sees a ticking time bomb in my approach to this. Thank you! -
Rules for changing cursor to HourGlass and back
Mike Torrettinni replied to Mike Torrettinni's topic in Tips / Blogs / Tutorials / Videos
I don't have experience with interfaces, but does this actually mean what it says: you just call SetTempCursor that creates Interface and when LongRun procedure is done, it will destroy interface automatically and re-set cursor? No need for local variable, no need for Interface=nil or something similar at the end of LongRun procedure that will trigger Destroy method? -
Rules for changing cursor to HourGlass and back
Mike Torrettinni replied to Mike Torrettinni's topic in Tips / Blogs / Tutorials / Videos
Wow, some complex implementation of cursor... when I changed to my simple 2 methods, I thought it is overkill 🙂 I'm not used to using try in my control handlers, usually 1 or 2 calls to methods and ShowMessage when needed. But it makes sense, of course using it for this case. -
Good practices with nested methods
Mike Torrettinni posted a topic in Tips / Blogs / Tutorials / Videos
I often use nested methods, mostly when a method needs 'helper' methods that are only applicable to it's logic. Here is how I usually setup my nested methods: procedure MainMethod(aParam: integer); // definitions can be accessed also from nested methods type TLocalUsed1 = record Field1: integer; end; var vArray: TArray<TLocalUsed1>; // nested methods procedure LocalMethod_WorkOnArray; var i: integer; begin for i := Low(vArray) to High(vArray) do // work on array end; function GetDataFromArray: integer; var i: integer; ab: TLocalUsed1; begin for i := Low(vArray) to High(vArray) do // work on array end; // definitions only accessible from main method type TLocalUsed2 = record Field1: integer; end; var i: integer; ab: TLocalUsed2; begin // use local vars and nested methods //... end; I used to have var i defined on top of all nested methods and I had issues with using i in main and nested methods, until I figured out the difference in scope of definitions. This works for me, but I was just thinking if there are any tips and tricks that can be used with nested methods, or some unique ways that you figure out how to use nested methods. Any feedback on using (or not using) nested methods is appreciated! Thanks!