Jump to content

Mike Torrettinni

Members
  • Content Count

    1509
  • Joined

  • Last visited

  • Days Won

    3

Everything posted by Mike Torrettinni

  1. Mike Torrettinni

    Overload methods or use unique names?

    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.
  2. Mike Torrettinni

    Overload methods or use unique names?

    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.
  3. 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).
  4. Mike Torrettinni

    How to manage defined list values

    Thank you, interesting idea, especially if they have very similar or even same structure.
  5. Mike Torrettinni

    How to manage defined list values

    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.
  6. Mike Torrettinni

    How to manage defined list values

    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?
  7. Mike Torrettinni

    How to manage defined list values

    Aha, I see. InitHelper initializes Caption, right? From const of names.., OR is Caption a function that return const_of_names[ptExternalDev]?
  8. Mike Torrettinni

    How to manage defined list values

    So, you use record helpers instead of: cProjCaptions[ptMain] ?
  9. Mike Torrettinni

    How to manage defined list values

    Are you talking about TCustomAttribute, like this answer: https://stackoverflow.com/questions/2134120/delphi-2010-rtti-explore-enumerations/2620883#2620883
  10. Mike Torrettinni

    How to manage defined list values

    Wow, so many different implementations, I had a problem choosing between the 2 I knew of 🙂
  11. Mike Torrettinni

    Deal - breaker: Registration Limit Increase

    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.
  12. Mike Torrettinni

    Deal - breaker: Registration Limit Increase

    Why? Issues with Delphi? Does Delphi detect multiple VMs running and gives problems with registration?
  13. 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?
  14. Mike Torrettinni

    Parse and Log method parameters

    Thanks for suggestions, will see what I can come up with.
  15. Mike Torrettinni

    Parse and Log method parameters

    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>;
  16. Mike Torrettinni

    Parse and Log method parameters

    Aha, I never used array of const, yet.
  17. Mike Torrettinni

    Parse and Log method parameters

    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.
  18. Mike Torrettinni

    Parse and Log method parameters

    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.
  19. Mike Torrettinni

    Parse and Log method parameters

    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.
  20. 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!
  21. Mike Torrettinni

    TArray vs TList with VirtualStringTree

    5 months later I had to come back to this to understand how to use direct access to record in TList<T>. Thanks again!
  22. 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!
  23. Mike Torrettinni

    Rules for changing cursor to HourGlass and back

    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?
  24. Mike Torrettinni

    Rules for changing cursor to HourGlass and back

    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.
  25. 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!
×