sglienke

Interface helper proposal

Aug 15th, 2014
580
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. program Project55;
  2.  
  3. {$APPTYPE CONSOLE}
  4.  
  5. uses
  6.   Rtti,
  7.   SysUtils,
  8.   TypInfo;
  9.  
  10. type
  11.   TLogEntry = record
  12.     msg: string;
  13.   end;
  14.  
  15.   ILogger = interface
  16.     procedure LogEntry(const entry: TLogEntry);
  17.   end;
  18.  
  19.   ILoggerHelper = record {helper for ILogger}
  20.   strict private
  21.     this: ILogger; // not necessary if this was a real helper as Self would point to ILogger
  22.   public
  23.     procedure LogValue<T>(const value: T);
  24.   end;
  25.  
  26.   TLogger = class(TInterfacedObject, ILogger)
  27.     procedure LogEntry(const entry: TLogEntry);
  28.   end;
  29.  
  30.   TLogEntryHelper = record helper for TLogEntry
  31.     procedure LogValue<T>(const value: T);
  32.   end;
  33.  
  34. var
  35.   GLogger: ILogger;
  36.  
  37. function Logger: ILogger;
  38. begin
  39.   Result := GLogger;
  40. end;
  41.  
  42. { TLogger }
  43.  
  44. procedure TLogger.LogEntry(const entry: TLogEntry);
  45. begin
  46.   Writeln(entry.msg);
  47. end;
  48.  
  49. procedure Main;
  50. var
  51.   s: string;
  52.   log: ILoggerHelper;
  53. begin
  54.   log := ILoggerHelper(Logger());
  55.   s := 'hello world';
  56. (*
  57.   lea eax,[ebp-$08]
  58.   mov edx,[ebp-$04]
  59.   call ILoggerHelper.LogValue<System.string>
  60. *)
  61.   log.LogValue(s);
  62.   log.LogValue(Now);
  63. end;
  64.  
  65. { ILoggerHelper }
  66.  
  67. procedure ILoggerHelper.LogValue<T>(const value: T);
  68. var
  69.   entry: TLogEntry;
  70. begin
  71. (*
  72.   lea eax,[ebp-$0c]
  73.   mov edx,[ebp-$08]
  74.   call TLogEntryHelper.LogValue<System.string>
  75. *)
  76.   entry.LogValue(value);
  77.   this.LogEntry(entry);
  78. end;
  79.  
  80. { TLogEntryHelper }
  81.  
  82. procedure TLogEntryHelper.LogValue<T>(const value: T);
  83. var
  84.   info: PTypeInfo;
  85.   kind: TTypeKind;
  86.   v: TValue;
  87. begin
  88.   info := System.TypeInfo(T);
  89.   kind := info.Kind;
  90.   v := TValue.From<T>(value);
  91.   case kind of
  92.     tkFloat:
  93.     begin
  94.       if info = System.TypeInfo(TDateTime) then
  95.         msg := DateTimeToStr(v.AsExtended)
  96.       else
  97.         msg := v.ToString;
  98.     end;
  99.   else
  100.     msg := v.ToString;
  101.   end;
  102. end;
  103.  
  104. begin
  105.   GLogger := TLogger.Create;
  106.   Main;
  107.   Readln;
  108.   ReportMemoryLeaksOnShutdown := True;
  109. end.
RAW Paste Data