Leaderboard
Popular Content
Showing content with the highest reputation on 01/21/21 in Posts
-
A very simple way to consume one Rest Api, just declaring one interface, based on .Net Refit: https://github.com/viniciusfbb/ipub-refit
-
Is it really that bad to Use boolean parameters to make your functions do two things?
Lars Fosdal replied to Mike Torrettinni's topic in General Help
EnableDisableWindow(WhyNot: boolean) -
TimSort for Delphi without Generics
Delphi-Laie replied to dummzeuch's topic in Algorithms, Data Structures and Class Design
OK, here my "official" answer (after my PN): In my sorting animation programm "Sortierkino" there are three Pascal (Delphi) implementations of Tim sort without any generics. But I'm interested in further variants of this algorithm and other sorting algorithms, sure. -
TimSort for Delphi without Generics
dummzeuch posted a topic in Algorithms, Data Structures and Class Design
As already stated in a different thread I have adapted the TimSort implementation for FreePascal I found on github to compile with Delphi 2007 (and probably earlier, but I haven't tried it). The source code is licensed under the Apache License 2.0 and available in my dzlib on OSDN. Note that this currently only sorts an array of integer and is still pretty rough. I'm going to refine quite a bit. There seem to be only 2 (now 2.5 š ) TimSort implementations in Pascal / Delphi available. (According to @David Heffernan there is also one in Spring4d.), but none that does not require generics. -
Thx, I solved my problem now and thx to @emailx45 for trying to help as well š
-
TimSort for Delphi without Generics
Delphi-Laie replied to dummzeuch's topic in Algorithms, Data Structures and Class Design
Dear Attila Kovacs, I thank you much for your attention, interest and help! Did / do you mean my program or me? I'm not really. But I have worked on this program since 2009 with several thousand programming hours. That is entitled / justified. I have shrinked for this effort und trouble (converting the x coordinates, switch to the rectangle instruction and so on) until now. Only at very few columns - necessary for pure bogo and bozo sorts, when they should finisch - is this a drawback, in my opinion. Small and moveable windows have got advantages too. Propably I'll be too lazy in the future to change my current solution. I don't know.... Very attentive! This mistake (more a Delphi property?!) I havn't not(ic)ed before. It doesn't appear at Lazarus compilats. It has got to do (or: is connected) with the fact that this is the only / single spinedit with a negative minimum value. It was a fairly, no, very subtle and hidden mistake. I needed a while (more than one hour) to detect and remove it. Now a corrected version that works better is published. Kindly regards, Delphi-Laie -
Is it really that bad to Use boolean parameters to make your functions do two things?
David Heffernan replied to Mike Torrettinni's topic in General Help
It's as if the thread above never happened!!!! -
@Attila Kovacs You are right about compatibility, thanks for checking this out. I will put this observation. In the future I can do some backwards compatibility, but not now. About the null values serialization, this library is just to consumes one rest api, then the serialization can occur just when you call a Post or Put and have the parameter ABody that is a record or a class or an array. In this specific case, the library will serialize the type as json, and in this case, the values that is null will be written to the json body without skip. The current implementation of System.JSON.Serializers donāt permit to ignore the fields with null values. Sorry i'll make it clearer
-
Is it really that bad to Use boolean parameters to make your functions do two things?
Attila Kovacs replied to Mike Torrettinni's topic in General Help
SetWindow'sVisibleFlagTo( clChequered ); -
Is it really that bad to Use boolean parameters to make your functions do two things?
Mike Torrettinni replied to Mike Torrettinni's topic in General Help
Good example. The syntax shows that boolean parameter actually controls to enable or disable window. Perhaps it would be better named EnableDisableWindow š https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-enablewindow -
Ah ok, its for creating an API consumer, (my first thought was something for declaring API's,, e.g. like in radserver (which we are using right now)).
-
Is it really that bad to Use boolean parameters to make your functions do two things?
balabuev replied to Mike Torrettinni's topic in General Help
My viewpoint to the topic's initial question: Whole WinAPI is written this way. I mean, almost every function provides flags parameter, which alters the function behavior. WinAPI also have examples of Enable/Disable like cases: ShowWindow(wnd, SW_HIDE); EnableWindow(wnd, FALSE); I thingk, it's ok, and it's a kind of well known pattern. -
Sorry I don't know what you mean and how to test serialization with an example of deserialization. There should be an option for nullables if "null" values should be serialized or not at all, but you will find this out by yourself one day if you start using this lib with php API's. Anyway, I tried to compile the lib with Berlin and there are couple of things which are only Tokyo+. (Very far from "perhaps XE7"). (Edit: even in Tokyo, System.JSON.Serializers is so buggy that it needs several workarounds) But System.JSON.Serializers.pas compiles fine under Berlin, thanks for bringing this unit to my attention.
-
This worked great on my application with Rad Studio Sydney 10.4.1, iOS 14.3 and Xcode 12.3. I had some issues of firing the OpenURL event, but now everything works as it should be. Thank you very much !
- 9 replies
-
- ios
- firemonkey
-
(and 6 more)
Tagged with:
-
Messageloop in Omnithread task
Primož GabrijelÄiÄ replied to merijnb's topic in OmniThreadLibrary
By default, an OTL task does not process windows messages (which is requirement for TTimer to work). To enfore windows message processing, call the MsgWait method of your task controller interface before running/scheduling the task. Like this: task := CreateTask(TWorker.Create()).MsgWait.Run; Read more here: http://www.omnithreadlibrary.com/book/chap07.html#lowlevel-tomniworker-msgwait -
@Attila Kovacs About the version of delphi supported, according to docwiki, the units System.JSON.XXX was introduced in Delphi 10 Seattle, but again I canāt guarantee itās compatible as it would need to be tested on these versions.
-
@Attila Kovacs I added support to register custom json converters. About the nullables, is very easy to implement the nullable and the converters. See one simple solution: uses System.Rtti, System.TypInfo, System.JSON.Serializers, System.JSON.Readers, System.JSON.Writers, System.JSON.Types, iPub.Rtl.Refit; type TNullable<T> = record IsNull: Boolean; Value: T; end; TNullableConverter<T> = class(TJsonConverter) public procedure WriteJson(const AWriter: TJsonWriter; const AValue: TValue; const ASerializer: TJsonSerializer); override; function ReadJson(const AReader: TJsonReader; ATypeInf: PTypeInfo; const AExistingValue: TValue; const ASerializer: TJsonSerializer): TValue; override; function CanConvert(ATypeInf: PTypeInfo): Boolean; override; end; { TNullableConverter<T> } function TNullableConverter<T>.CanConvert(ATypeInf: PTypeInfo): Boolean; begin Result := ATypeInf = TypeInfo(TNullable<T>); end; function TNullableConverter<T>.ReadJson(const AReader: TJsonReader; ATypeInf: PTypeInfo; const AExistingValue: TValue; const ASerializer: TJsonSerializer): TValue; var LNullable: TNullable<T>; begin if AReader.TokenType = TJsonToken.Null then begin LNullable.IsNull := True; LNullable.Value := Default(T); end else begin LNullable.IsNull := False; LNullable.Value := AReader.Value.AsType<T>; end; TValue.Make<TNullable<T>>(LNullable, Result); end; procedure TNullableConverter<T>.WriteJson(const AWriter: TJsonWriter; const AValue: TValue; const ASerializer: TJsonSerializer); var LNullable: TNullable<T>; LValue: TValue; begin LNullable := AValue.AsType<TNullable<T>>; if LNullable.IsNull then AWriter.WriteNull else begin TValue.Make<T>(LNullable.Value, LValue); AWriter.WriteValue(LValue); end; end; initialization GRestService.RegisterConverters([TNullableConverter<string>, TNullableConverter<Byte>, TNullableConverter<Word>, TNullableConverter<Integer>, TNullableConverter<Cardinal>, TNullableConverter<Single>, TNullableConverter<Double>, TNullableConverter<Int64>, TNullableConverter<UInt64>, TNullableConverter<TDateTime>, TNullableConverter<Boolean>, TNullableConverter<Char>]); end. To use just replace the simple types to the nullable types: TUser = record Name: TNullable<string>; Location: string; Id: Integer; Email: TNullable<string>; end; [BaseUrl('https://api.github.com')] IGithubApi = interface(IipRestApi) ['{4C3B546F-216D-46D9-8E7D-0009C0771064}'] [Get('/users/{user}')] function GetUser(const AUser: string): TUser; end; procedure TForm1.FormCreate(Sender: TObject); var LGithubApi: IGithubApi; LUser: TUser; begin LGithubApi := GRestService.&For<IGithubApi>; LUser := LGithubApi.GetUser('viniciusfbb'); end; You can test the code above and see the user name is not null but the user email is null. The nullable type and the nullable converter code in this example need to be implemented by the developer, I can't put it on the library because each developer has it own implementation os nullable.
-
TimSort for Delphi without Generics
Attila Kovacs replied to dummzeuch's topic in Algorithms, Data Structures and Class Design
@Delphi-Laie This is really cool man! A suggestion, don't know if it's possible, when the column count is reduced it should not shrink the window width but widen the columns. (Maybe some value would also fit in the columns.) PS: if you delete the "0" in the field "Rotation" the app AV's and dies. -
Customizing source editor
Gary Mugford replied to Mike Torrettinni's topic in Tips / Blogs / Tutorials / Videos
As I mentioned, not everybody has my taste in colour. My house is decorated in green and brown. This is a logical continuation. And yes, It DOES work better with a dark-themed IDE outside of the editor. So I completely understand Lars. As for Mike and Stano and any others, maybe try a darker green. Really, it IS easier on your eyes. Limit the variation between the various sections ... the light green ones are areas I don't get too all that often being a basic stick in the mud procedural programmer. So, there is less striations in real time use for me. Again, depending on your complexity level necessitating more of the various coding sections, well complexity has a price. There MIGHT be a compromise hue of Green between mine and black, which is what you are going to default to with Dark Theme. I have NOT had to involve myself with Styles but it is rearing it's potentially pretty little head now that I've experienced a fellow who decided he wanted a YELLOW BACKGROUND as the Win 10 default. Not gold, not amber, not honey, not parchment, YELLOW. And he's asked if he could personalize his interface. Ahhhhhh, no, not right now. But maybe in a month I'll revisit it ... hoping a month is 14 days more than his career at that company. But if he sticks, then I'll be looking strongly at Almediadev. YELLOW! -
Hi, I had this problem and coped with it this way : In project/options/version information/CFBundleName, put : $(ModuleName) For me it runs fine now
-
TimSort for Delphi without Generics
dummzeuch replied to dummzeuch's topic in Algorithms, Data Structures and Class Design
Fixed the string order issue. -
TimSort for Delphi without Generics
dummzeuch replied to dummzeuch's topic in Algorithms, Data Structures and Class Design
Here are some timings: sorted reverse half random QuicksortInteger(1000000): 0.05787 0.06269 not done 0.16328 QuickSortPlusInteger(15)(1000000): 0.04744 0.04995 0.24928 0.14548 TimSortInteger(1000000): 0.00214 0.00252 0.00981 0.16411 QuicksortString(1000000): 1.36692 1.00144 not done 1.16640 QuickSortPlusString(15)(1000000): 1.38534 0.99298 0.81605 1.23809 TimSortString(1000000): 0.06285 0.09036 0.16268 1.86726 Sorting 1 million integers or strings respectively. The strings are simply generated with IntToStr for numbers 0 to 999,999 and compared with CompareStr. This means that Sorted, Reverse and half for strings is not really correct, because '10' < '2' etc. I need to fix that, but this is not too bad a dataset for sorting tests either. (I just googled and found that apparently there are some test datasets for sorting algorithm performance. I'll have a look into that.) The numbers are the time in seconds for a single run on my computer. As you can see, TimSort is faster than all of them with the exception of random data, where it is still in the same ballpark. The test program is in the subdirectory Tests\SortingTests. Please note that with the exception of TimSort, these sorting algoritmms are not implemented for best performance but for convenience: They are abstracted from the data and use callbacks to compare and swap items. TimSort currently works directly on the data and uses a callback only for comparison, but my goal is to abstract the algorithm from the data in a similar manner, if possible. -
TimSort for Delphi without Generics
dummzeuch replied to dummzeuch's topic in Algorithms, Data Structures and Class Design
My implementation now uses Pseudo Templates based on include files (please note that the linked article is ancient, so take its C++ references with a grain of salt), so it should be compatible with most Delphi versions (tested with Delphi 2007 and 10.2). The source is on OSDN in my dzlib. It has been tested with sorting dynamic arrays of integers and strings, but should work with anything else that does not include reference counting (so no interfaces yet). It's much slower for strings because of the special code in the MoveItems method which allows for reference counting (for strings, should also ). Unit tests are in the UnitTests\SortingTest subdirectory of dzlib. The units declaring TimSort for Integer and String arrays use the above mentioned template. To get the source, use SubVersion to create a working copy from http://svn.osdn.net/svnroot/dzlib-tools/dzlib/trunk -
@Dave Nottage Hi Dave, I tested and works perfectly!! Thanks you so much, you are the man!! Just to register here the complete solution. (I preferred to patch the delphi source files because I already have others patchs in that files) iOS - Handle incoming url (custom schemes or universal links) In the file iOSapi.Foundation.pas put the code: // Dave Nottage code (https://www.delphiworlds.com/) NSUserActivityPersistentIdentifier = NSString; TNSUserActivityBlockMethod1 = procedure(inputStream: NSInputStream; outputStream: NSOutputStream; error: NSError) of object; TNSUserActivityBlockMethod2 = procedure of object; NSUserActivityClass = interface(NSObjectClass) ['{412EAEBF-5927-4D01-B83F-69D3B5DFE7B5}'] {class} procedure deleteAllSavedUserActivitiesWithCompletionHandler(handler: TNSUserActivityBlockMethod2); cdecl; [MethodName('deleteSavedUserActivitiesWithPersistentIdentifiers:completionHandler:')] {class} procedure deleteSavedUserActivitiesWithPersistentIdentifiers(persistentIdentifiers: NSArray; handler: TNSUserActivityBlockMethod2); cdecl; end; NSUserActivity = interface(NSObject) ['{B8C2F6C9-31FE-4282-B7CA-98C96E163033}'] function activityType: NSString; cdecl; procedure addUserInfoEntriesFromDictionary(otherDictionary: NSDictionary); cdecl; procedure becomeCurrent; cdecl; function delegate: Pointer; cdecl; function expirationDate: NSDate; cdecl; procedure getContinuationStreamsWithCompletionHandler(completionHandler: TNSUserActivityBlockMethod1); cdecl; function initWithActivityType(activityType: NSString): Pointer; cdecl; procedure invalidate; cdecl; function isEligibleForHandoff: Boolean; cdecl; function isEligibleForPrediction: Boolean; cdecl; function isEligibleForPublicIndexing: Boolean; cdecl; function isEligibleForSearch: Boolean; cdecl; function keywords: NSSet; cdecl; function needsSave: Boolean; cdecl; function persistentIdentifier: NSUserActivityPersistentIdentifier; cdecl; function referrerURL: NSURL; cdecl; function requiredUserInfoKeys: NSSet; cdecl; procedure resignCurrent; cdecl; procedure setDelegate(delegate: Pointer); cdecl; procedure setEligibleForHandoff(eligibleForHandoff: Boolean); cdecl; procedure setEligibleForPrediction(eligibleForPrediction: Boolean); cdecl; procedure setEligibleForPublicIndexing(eligibleForPublicIndexing: Boolean); cdecl; procedure setEligibleForSearch(eligibleForSearch: Boolean); cdecl; procedure setExpirationDate(expirationDate: NSDate); cdecl; procedure setKeywords(keywords: NSSet); cdecl; procedure setNeedsSave(needsSave: Boolean); cdecl; procedure setPersistentIdentifier(persistentIdentifier: NSUserActivityPersistentIdentifier); cdecl; procedure setReferrerURL(referrerURL: NSURL); cdecl; procedure setRequiredUserInfoKeys(requiredUserInfoKeys: NSSet); cdecl; procedure setSupportsContinuationStreams(supportsContinuationStreams: Boolean); cdecl; procedure setTargetContentIdentifier(targetContentIdentifier: NSString); cdecl; procedure setTitle(title: NSString); cdecl; procedure setUserInfo(userInfo: NSDictionary); cdecl; procedure setWebpageURL(webpageURL: NSURL); cdecl; function supportsContinuationStreams: Boolean; cdecl; function targetContentIdentifier: NSString; cdecl; function title: NSString; cdecl; function userInfo: NSDictionary; cdecl; function webpageURL: NSURL; cdecl; end; TNSUserActivity = class(TOCGenericImport<NSUserActivityClass, NSUserActivity>) end; ... function NSUserActivityTypeBrowsingWeb: NSString; ... implementation ... function NSUserActivityTypeBrowsingWeb: NSString; begin result := CocoaNSStringConst(FoundationFwk, 'NSUserActivityTypeBrowsingWeb'); end; In the file FMX.Platform.iOS.pas, in the TApplicationDelegate class, in the private section, put the code: class function applicationContinueUserActivityRestorationHandler(self: id; _cmd: SEL; application: PUIApplication; userActivity: Pointer; restorationHandler: Pointer; restorableObjects: Pointer): Boolean; cdecl; static; In the file FMX.Platform.iOS.pas, in the implementation of the method TApplicationDelegate.CreateDelegateMetaClass, before the line "objc_registerClassPair(DelegateClass);", put the code: class_addMethod(DelegateClass, sel_getUid('application:continueUserActivity:restorationHandler:'), @applicationContinueUserActivityRestorationHandler, 'B@:@@@@'); In the file FMX.Platform.iOS.pas, in the TApplicationDelegate implementation, put the code: class function TApplicationDelegate.applicationContinueUserActivityRestorationHandler( self: id; _cmd: SEL; application: PUIApplication; userActivity, restorationHandler, restorableObjects: Pointer): Boolean; var LUserActivity: NSUserActivity; LURLString: string; begin Result := False; if Assigned(userActivity) then begin LUserActivity := TNSUserActivity.Wrap(userActivity); if NSStrToStr(LUserActivity.activityType) = NSStrToStr(NSUserActivityTypeBrowsingWeb) then begin if Assigned(LUserActivity.webpageURL) then LURLString := NSStrToStr(LUserActivity.webpageURL.absoluteString) else LURLString := string.Empty; Result := PlatformCocoaTouch.HandleApplicationEvent(TApplicationEvent.OpenURL, TiOSOpenApplicationContext.Create(string.Empty, LURLString, nil)); end; end; end; Usage uses System.Messaging, FMX.Platform, FMX.Platform.iOS, FMX.Dialogs; constructor TipUrlHandler.Create; begin inherited Create; TMessageManager.DefaultManager.SubscribeToMessage(TApplicationEventMessage, ApplicationEventMessageHandler); end; destructor TipUrlHandler.Destroy; begin TMessageManager.DefaultManager.Unsubscribe(TApplicationEventMessage, ApplicationEventMessageHandler, True); inherited; end; procedure TipUrlHandler.ApplicationEventMessageHandler(const ASender: TObject; const AMessage: TMessage); begin case TApplicationEventData(TApplicationEventMessage(AMessage).Value).Event of TApplicationEvent.OpenUrl: begin Showmessage(TiOSOpenApplicationContext(TApplicationEventData(TApplicationEventMessage(AMessage).Value).Context).URL); end; else end; end;
- 9 replies
-
- ios
- firemonkey
-
(and 6 more)
Tagged with:
-
Yes, the application delegate needs to implement this method: https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623072-application?language=objc This means class_addmethod will need to be called to add it to the delegate (DelphiAppDelegate). It will also need an import for NSUserActivity, one of which follows (no guarantees as to being 100% accurate): NSUserActivityPersistentIdentifier = NSString; TNSUserActivityBlockMethod1 = procedure(inputStream: NSInputStream; outputStream: NSOutputStream; error: NSError) of object; TNSUserActivityBlockMethod2 = procedure of object; NSUserActivityClass = interface(NSObjectClass) ['{412EAEBF-5927-4D01-B83F-69D3B5DFE7B5}'] {class} procedure deleteAllSavedUserActivitiesWithCompletionHandler(handler: TNSUserActivityBlockMethod2); cdecl; [MethodName('deleteSavedUserActivitiesWithPersistentIdentifiers:completionHandler:')] {class} procedure deleteSavedUserActivitiesWithPersistentIdentifiers(persistentIdentifiers: NSArray; handler: TNSUserActivityBlockMethod2); cdecl; end; NSUserActivity = interface(NSObject) ['{B8C2F6C9-31FE-4282-B7CA-98C96E163033}'] function activityType: NSString; cdecl; procedure addUserInfoEntriesFromDictionary(otherDictionary: NSDictionary); cdecl; procedure becomeCurrent; cdecl; function delegate: Pointer; cdecl; function expirationDate: NSDate; cdecl; procedure getContinuationStreamsWithCompletionHandler(completionHandler: TNSUserActivityBlockMethod1); cdecl; function initWithActivityType(activityType: NSString): Pointer; cdecl; procedure invalidate; cdecl; function isEligibleForHandoff: Boolean; cdecl; function isEligibleForPrediction: Boolean; cdecl; function isEligibleForPublicIndexing: Boolean; cdecl; function isEligibleForSearch: Boolean; cdecl; function keywords: NSSet; cdecl; function needsSave: Boolean; cdecl; function persistentIdentifier: NSUserActivityPersistentIdentifier; cdecl; function referrerURL: NSURL; cdecl; function requiredUserInfoKeys: NSSet; cdecl; procedure resignCurrent; cdecl; procedure setDelegate(delegate: Pointer); cdecl; procedure setEligibleForHandoff(eligibleForHandoff: Boolean); cdecl; procedure setEligibleForPrediction(eligibleForPrediction: Boolean); cdecl; procedure setEligibleForPublicIndexing(eligibleForPublicIndexing: Boolean); cdecl; procedure setEligibleForSearch(eligibleForSearch: Boolean); cdecl; procedure setExpirationDate(expirationDate: NSDate); cdecl; procedure setKeywords(keywords: NSSet); cdecl; procedure setNeedsSave(needsSave: Boolean); cdecl; procedure setPersistentIdentifier(persistentIdentifier: NSUserActivityPersistentIdentifier); cdecl; procedure setReferrerURL(referrerURL: NSURL); cdecl; procedure setRequiredUserInfoKeys(requiredUserInfoKeys: NSSet); cdecl; procedure setSupportsContinuationStreams(supportsContinuationStreams: Boolean); cdecl; procedure setTargetContentIdentifier(targetContentIdentifier: NSString); cdecl; procedure setTitle(title: NSString); cdecl; procedure setUserInfo(userInfo: NSDictionary); cdecl; procedure setWebpageURL(webpageURL: NSURL); cdecl; function supportsContinuationStreams: Boolean; cdecl; function targetContentIdentifier: NSString; cdecl; function title: NSString; cdecl; function userInfo: NSDictionary; cdecl; function webpageURL: NSURL; cdecl; end; TNSUserActivity = class(TOCGenericImport<NSUserActivityClass, NSUserActivity>) end; The method implementation should probably be (again no guarantees): class function TApplicationDelegate.applicationContinueUserActivityRestorationHandler(self: id; _cmd: SEL; application: PUIApplication; userActivity: Pointer; restorationHandler: Pointer): Boolean; As far as I know, it doesn't necessarily have to be patched in FMX.Platform.iOS since you should be able to call class_addmethod anywhere, as long as you pass it the correct class function. Hopefully this will give you head start.
- 9 replies
-
- ios
- firemonkey
-
(and 6 more)
Tagged with: