-
Content Count
1264 -
Joined
-
Last visited
-
Days Won
26
Everything posted by David Schwartz
-
Which implementation of this is easier to understand?
David Schwartz replied to dummzeuch's topic in Algorithms, Data Structures and Class Design
Is there a ReadBuffer operation? If not, maybe create one that's a function returning True if it read enough data and False otherwise. This way you could use a While loop to step through successive records rather than a for loop that keeps doing a seek each time just to go to the next record. The pointer should already be there, so why keep resetting it each time? Also, it bothers me that your logic uses Exceptions when something isn't found, but maybe it's that serious if data is missing. -
Which implementation of this is easier to understand?
David Schwartz replied to dummzeuch's topic in Algorithms, Data Structures and Class Design
Dang, I never noticed that. I've tried everything I could think of but not this. Thanks! But it would still be nice to have a way to get the index corresponding to an iterator position in a list somehow. -
Which implementation of this is easier to understand?
David Schwartz replied to dummzeuch's topic in Algorithms, Data Structures and Class Design
I like the second simply because it's shorter. I also wish there was a better mechanism available but suspect it would end up looking rather like a Case statement, sort of like Awk scripts. I don't know why any of these are anti-patterns because the alternative is ugly-patterns that are harder to read and add unnecessary logic. You could change it to a while or repeat...until structure, but they both require an initial probe at the top; while requires some kind of 'get-next' at the bottom of the loop; and repeat...until always seems to need a check near the bottom for make-or-break unless you want to add another variable to the loop test, which always seems redundant to me. This is the problem: you have two independent variables involved: one controls the loop, and the other interupts it if it finds a resolution before the whole sample set has been exhausted, which only improves performance. To be more precise with your expressions, the for loop would contain two tests, one for each variable. This is easy in C/C++ for loops, but not in Delphi/Pascal. Instead, you'd need a while or repeat...until. But as I said, you can only initilize and work with one variable in the for statement in Pascal; again, C/C++ makes it easy. So Pascal leaves us with a half-assed solution, exemplified by this: var sl := TStringlist.Create; // add a bunch of things with objects to the list ... sl.AddObject( aString, someObject ); // this deceptive call makes it look like there's a relationshiop between aString and someObject, // but there actually isn't because they have separate indices! // They DO happen to coincide, however. // Sadly, neither sl[aString] nor sl[aString].Object leads to the corresonding entry in Objects that yields this pair. ... // now find and return an object function findSomething( const aStringArg : string ) : TObject; begin Result := NIL; for var str in sl do if (str = aStringArg) then Exit( sl.Objects[ ??? ]; // oops ... no way to get the corresponding item in Objects! // you are forced to go this way instead for var i := 0 to sl.Count-1 do if (aStringArg = sl[i]) then Exit( sl.Objects[i] ); end; The for...in is a much cleaner way to go, but the fact that the embedded Objects array requires the item's index to access its contents mucks things up. So you need to drag in a separate index just to satisfy that need. You could say this is a fault in the design of TStringlist, but it's a widespread problem. Again, C/C++ solves it nicely by allowing multiple independent variables to be used in a For loop. Perhaps for TStringlists, it would be better if the iterator had a hidden index that could be used to probe into the Objects array: for aStr in sl do if (aStr = sStringArg) then Exit( sl.Selected.$Object ); // Selected would be a new property introduced into the iterator allowing the // Object property to find the index associated with this entry to extract a value So maybe it's a limitation in how Deplhi implements iterators rather than TStringlists (and every other class that has a similar problem). -
The Enterprise license includes a bunch of FD Enterprise Connectors from CDATA. I grabbed some for D10.3, but I have not been able to find them for 10.4. (I can't even find the ones for 10.3 now either.) Anybody know where to find them?
-
Where are the FD Enterprise Connectors hiding?
David Schwartz replied to David Schwartz's topic in General Help
It seems really hard to justify paying nearly the same price for a single "connector" as it costs to maintain Delphi, but if this doesn't even include the ability to distribute software you used it for, then it's a no-brainer. I guess they're more like EMBT in that they make most of their revenues from companies who just keep renewing their license fees every year just so they don't get caught with their pants down at some point because of a decision years earlier to use some of their products. -
enable/disable the internet connection?
David Schwartz replied to David Schwartz's topic in Windows API
Yes, I found an option to do that. But the question was and still is "Is there an API call to do this from a Delphi app" not "is there a windows setting button somewhere that does this". Q: "What's a good pair of boots I can wear at the beach?" A: "The weather is great, so why not just wear flip-flops?!" A: "Crocs are really the best thing to wear at the beach" A: "I prefer going barefoot" A: <photo of toe-socks> A: "My gf hates boots. Here's what she has me wear" <photo attached> -
enable/disable the internet connection?
David Schwartz replied to David Schwartz's topic in Windows API
I have no idea what goes on behind the scenes with MacOS, but it does let me say not to install updates and it mostly respects that. Sometimes it does show a little thing that says there's an update and I can click Cancel or Install. Sometimes one of the options is "wait until tomorrow". I don't even like to install MacOS updates. The problem with Windows is it downloads a bunch of files, then it starts running crap in the background and eats up 50% of the CPU for 30-45 minutes, then it tells me there's an update and keeps bugging me about it. I have the updater supposedly disabled. I have searched and shut off everything I've found, and yet it continues to download crap and run that background thing, and then tells me it needs to reboot. I can put it off for a while, but I shut off the VM when I'm not working with it because if the host crashes it can totally screw up the VM if it was open and doing anything. That's part of the reason I shut it off ... because windows is constantly doing background stuff when I'm inactive for 10 minutes or so. Win7 would just sit there and do nothing. Win10 seems to have a bunch of little elves scurrying around constantly doing stuff and there's no way to shut them down. I know how to open the internet panel and drill-down and enable / disable the network interface in Windows. The VM won't let you turn it on or off while it's running -- you actually have to shut off the VM (not just put it to sleep). It's as if you're unplugging the LAN card. Windows will let you delay only so long before it FORCES a reboot on you, whether you want it or not. And frequently it will start a count-down timer that's hidden beneath another window so you can't see it. I've had that happen in the middle of builds. The timer window appears below Delphi when I kicked off a build, and then a little later I saw a popup that said, "Windows is restarting..." and POOF! Then it shows a screen "Windows is updating, do not power down!" and it goes on for 10-15 minutes. I have NEVER had this happen EVER with MacOS or any Apple product. Laptops employers have provided me with do this kind of thing almost weekly. But that's by design. I can't complain about it. But when it's MY machine, I WANT TO BE ABLE TO TELL MICROSOFT AND ITS MINIONS "DO NOT MESS WITH THIS MACHINE!" That seems to be imposible except by shutting off the internet when you're not using it. I just want a little box with an OFF / ON switch for that. You guys are all entitled to your own opinions and your threshold of getting annoyed of being bullied by the OS is whatever it is. I have a lot tolerance for that -- when I'm busy working on something, I don't like to be interrupted by something like a 2-yo that decides to pull the plug on the computer to get your attention. And no, I don't have kids, partly for that reason. -
I'm calling a service and I get back a JSON response packet that's got a bunch of sections in it, and each one has a structure to it. Most contain an array of things; some of those items themselves contain arrays, and some contain a list of items. I'm using TJSONObject to process this data. What I'm doing is picking out two sections, say ARY1 and ARY2. One can have 10-20 elements and the other 3-5. Then I go through them using a for...in statement, and for each of the elements, I have code that picks out a half-dozen field values that I'm interested in (among 10-20 in each type of element). Eg, ntry1.TryGetValue<integer>('request_info.credits_used', FCreditsUsed); ntry1.TryGetValue<integer>('request_info.credits_remaining', FCreditsRemaining); From time to time, one or more of the field values is missing -- meaning the name isn't there. If it's there and it's blank, that's fine. But since they can be missing, I have to use TryGetValue<T>(...) everywhere which is rather cumbersome. Each one of these elements gets loaded into a class instance which is put into a TList<T> collection. Another class contains the two TList<T> collections (representing the two arrays) and then I use that to process the data. I might have 10 to 50 or so of these in a matrix. I could put the two arrays into different TDatasets, but I don't really see any benefit in that. Is this approach what would typically be taken? Or would it be more typical to just access things in the JSONObject directly? eg., if doc.TryGetValue<string>('a.b['+n.ToString+'].'+aFldName, s) then fFldName = s else fFldName = ''; where 'n' indicates which array (1 or 2) and each aFldName is referred in each in each. This approach seems very brittle. But it seems a bit simpler. So I'm sticking with my classes and lists. (But I have something not being freed properly that's being quite a PITA to track down, and I'm thinking it's related to the structures I'm using.) I haven't seen any examples that show JSON processing where non-trivial data is being retrieved, so I'm just curious if there are better approaches.
-
This sounds about right. Doing compiles is like flooring the pedal in your car at a stop light when the light turns green. I run Delphi inside of VirtualBox on my Mac, which has 36GB of RAM, a 6-core i7 CPU, and 2TB of SSD. The odd-numbered cores all go to about 80% when I do a compile that takes more than a few seconds. There's always a "weakest link" no matter how fast everything runs. If you'r CPU isn't saturated, then your RAM or DISK is limiting things to some extent. And who knows what's going on with the GPU during compiles!
-
Are you using Delphi 11 with mainstream projects?
David Schwartz replied to Clément's topic in Delphi IDE and APIs
I always wait for the first "bug-fix update" after each major release before doing anything with it. I'm still having plenty of problems with 10.4.2. -
Interesting ... is this 'expert' accessible somewhere?
-
Someone posed the following problem: You have two video cameras. Camera #1 is focused on a person seated in a chair against some static background. Camera #2 is focused on something else (eg, waves on the beach) Step #1: identify the person vs. the background in video stream #1; and then, Step #2 replace the background with the video stream from camera #2 and display the composited video stream. (audio would be from camera #1.) I know Zoom lets you pick a static image or even a short video clip and use it as the background on your main camera. It does not let you use a second live video stream, but I suspect that this wouldn't be difficult to substitute for the looped video snippet. Is anybody familiar enough with video libraries and resources to know if there's a way to do that easily with existing libraries somewhere that work with Delphi?
-
And of course you don't even need selfie mode on the camera since you can simply turn the phone around and point the camera at yourself. That eliminates the need for the second camera. Or just use a separate camera entirely and dump the cameras from the cell phone. It's a PHONE after all, right?
-
I recall reading somewhere about how to split up the Interface and implementation parts of a unit into diferent files. It may have been a chapter in a Delphi book as opposed to something online. I'm wondering if anybody remembers this and can tell me where to find it? I've got a pile of Delphi books, most are eBooks on Kindle, and I have not had any luck searching for it because of so many overloads of these terms.
-
Is it possible to activate both the front and rear video cameras on phones simultaneously and work with both video streams at the same time in your app?
-
looks like the answer is "not very likely"
-
splitting interface + implementation
David Schwartz replied to David Schwartz's topic in General Help
My question was if anybody knows the BOOK that contains a discussion of this topic? I'm looking for the chapter in a BOOK where this is discussed. It was a DELPHI book, possibly by Nick Hodges -
Sorry, to clariy further: I'm wondering about building a mobile app in Delphi, possibly a web app. OBS is a desktop app.
-
splitting interface + implementation
David Schwartz replied to David Schwartz's topic in General Help
That's what I was thinking, too. But I skimmed through the two "Coding in Delphi" books and didn't find it. Maybe the DI book? -
I started working with Delphi when it was first released in 1995. Prior to that I did embedded real-time work in C and was learning OOP with C++ when Delphi came out. For me, the 1990's were the most fun I've had in my entire career. I worked for a series of startups as their Chief Architect and Developer. They all died for various (non-technical) reasons, although one came very close to breaking out and becoming something significant. (Most of the people I worked with at Intel from 79 thru the mid-80's all went on to work with one or more startups and they all became multi-bazillionaires, a few even became billionaires.) By 2000 I was working entirely with Delphi. I really loved it. There was a lot of new work going on with it and it was a lot of fun. But by 2010, Delphi had been around for 15 years. Code had started to accumulate where the original dev teams had moved on ... to the point where there were well-paying contract gigs for people who had 5+ years of experience with Delphi, and I chased after them, but they got harder and harder to find. The next 10 years was a mix of contracts and regular jobs where the companies said they were looking for "experienced Delphi developers to lead projects". But they pretty much all turned into glorified maintenance roles. Over time, each new company / project got stricter and stricter in terms of what they would allow, and virtually none of it involved new product development. That was all being done in C#/.NET and the existing devs got to move to that stuff while contractors were hired to back-fill and keep the Delphi code running. It seems like the longer you work in a specific technology, the more expertise you're going to accumulate, and the more likely you are to be hired to maintain critical systems that use that technology. Companies like to invest in risk-reduction, so they seem to like hiring experts who are over-qualified for maintenance work. (Except recruiters from places like India who always say "I'm sorry Mr. David, but the client can't pay more than $21, maybe $22 per hour for someone with 10+ years of experience". They're trying to document that they cannot find Americans to hire in order to justify H1-B workers.) The Good News is that I just turned 65 and got on Social Security. I no longer have to deal with this crap just to survive, and I can start looking around for things that I *WANT* to do and I don't have to worry about the pay. I feel like I did when graduated from college! Except I'm now free of the "rat race" so I can really have some FUN with this technology. I've got some things I'm working on for myself, and was invited to be on the advisory board of a startup already. Things are really looking up.
-
Object Pascal Handbook - Delphi 10.4 Sydney Edition - Marco Cantù (2020) - 571pg
David Schwartz replied to a topic in Tips / Blogs / Tutorials / Videos
I think the original edition of this version was. But as he started updating it for different sub-versions, I don't recall seeing it. But I agree. -
Class Instance vs Object Instance
David Schwartz replied to bravesofts's topic in Algorithms, Data Structures and Class Design
This is a link to a section on this site where you can download a free copy of Marco's book: https://en.delphipraxis.net/topic/4418-object-pascal-handbook-delphi-104-sydney-edition-marco-cantù-2020-571pg/ -
Instead of hijacking this thread with yet another off-topic wall of text about why Embarcadero sucks and Delphi is doomed, maybe you could start your own thread? This was in reponse to the OP who posted a bunch of suggestions for delphi from a Developer's perspective. There have been tons of such posts here and elsewhere over the past decade, some quite eloquent and some more debatable. This discussion forum is dominated by DEVELOPERS, like you and I. We have our perspectives, we love Delphi and we all pretty much would LOVE to see it continue to grow and expand and get better. But after all of the proposals, submissions through official channels, and every conceivable attempt at begging, prodding, and encouraging Embt to do different things, it has become painfully obivous that ... they just are not interested. They don't "suck". They are operating in the best interests of their SHAREHOLDERS. We are DEVELOPERS -- NOT SHAREHOLDERS! SHAREHOLDERS want PROFITS while we DEVELOPERS want MORE FEATURES! Any overlap is mostly coincidence, driven primarily by Microsoft and Apple. Not us Developers. The CUSTOMERS paying the bills want LOW-RISK INVESTMENTS. Everywhere I've worked in the past 10+ years has had one thing in common: they only want me to touch code that HAS TO BE CHANGED. They don't want me to use NEW FEATURES. They don't want REFACTORING. They don't want the code "cleaned-up". A couple changed their policies that require every line that shows up as changed in the change logs must relate back to a specific trouble ticket. "Refactoring" for its own sake was not allowed. They DO want: simple, straightforward changes that use existing coding patterns and language features found in D7-era code (around when the apps were built) so it looks and behaves the same as all the rest of their code. The last place I worked, most of the core code they used in production had not been touched since 2007. I was told on my first day, "DO NOT TOUCH ANY OF THE CODE WITHOUT MY APPROVAL!" I found and documented several bugs, and was told point-blank, "you must be wrong, this code has not changed in over a decade; there are no bugs in it." Except it went from running in Win XP to Win 7 to Win 10, and now it does weird and unexpected stuff sometimes that I captured on camera. They didn't want to hear about it. I asked one Dept head (at a State Agency) why they don't rebuild their code in the latest version of Delphi using more contemporary stuff. His answer: Because their State's CTO basically said, "All new software development will be done in C#/.NET." Period. End of story. Seems their Legislature authorized a 10-year agreeement with Microsoft to provide them with everything they'd need, and that was that. I've heard similar things from multiple places I've worked, both public and private. This is NOT MY OPINION! I personally don't think Embt "sucks". I personally don't think Delphi is "doomed". I think Delphi's evolution is being dictated by two things: (1) SHAREHOLDERS who are only interested in profits; and (2) CUSTOMERS who are interested in REDUCING RISKS IN EXISTING PRODUCTION CODE. I love Delphi. I love the Developer community. And I don't see Embt's focus on Delphi changing any time soon to make it more aligned with that of Developers other than coincidentally. For example, I've seen dozens of proposals for language extensions, many of which would be useful to most Delphi Deverlopers on an almost daily basis. But the only two that were added to D11 ... I've never ever seen discussed. I was honestly totally surprized when inline 'var' declarations appeared in the language. That's a marginally useful feature to me, and not one I would have ever expected to see added. But its introduction broke a bunch of far more useful things in the IDE. They would have been better off not introducing it until everything in the IDE worked properly with it. D11 reportedly hasn't fixed anything that was in D10.4.2. The last place I worked, we were asked after D10.3 came out if there was anything added to the language that might justify the risk of upgrading everything. Inline vars were all there was, and the consensus was that they did not justify anything, especially because they broke a lot of stuff in the IDE. Unfortunately, the company went ahead and paid the maintenance fee anyway. Why? Because the cost of NOT paying was more risky and costly. Yet we're still waiting for MANY VERY USEFUL ADDITIONS to the language! This is how the game has been rigged: customers (companies) will continue to pay their maintenance fees whether they use what's been added or not. And SHAREHOLDERS LOVE THAT! Developers ... not so much.
-
Class Instance vs Object Instance
David Schwartz replied to bravesofts's topic in Algorithms, Data Structures and Class Design
YES IT DOES! It allocatess space on the stack for a POINTER (assuming it's inside of a method). When you say this: vObj_Instance := TClass_Type.Create(...); it allocates a chunk of memory from the heap, sets vObj_Instance to point to it, then calls the constructor with an implicit pointer argument to that chunk of memory and initializes it based on the code in the chain of constructors that get called. If TClass_Type is defined as a RECORD, then it would allocate enough space on the stack to fit the entire record, and you would not need to allocate space for it from the heap. In C/C++ this would be written as: TClass_Type * vObj_Instance; // allocates space for a typed POINTER // this is the constructor call equivalent to what happens in Delphi vObj_Instance = new TClass_type(...); This is more clear, showing that it's a POINTER type. In Dephi, the call to allocate space from the heap (by 'new' in C++) is always IMPLED. -
Class Instance vs Object Instance
David Schwartz replied to bravesofts's topic in Algorithms, Data Structures and Class Design
well, you seem more familiar with what Pascal offered, before Dephi introduced 'class' types. And I don't know what to say about the question regarding EXEs. That's totally unrelated to storage allocation of classes. Or I'm not understanding your question. See if you can snag a copy of Marco's book (ask Google) and work your way through it. That will get you onto very solid ground.