Jump to content


  • Content Count

  • Joined

  • Last visited

  • Days Won


Everything posted by lennart

  1. Yep, i usually do this from the chrome console, but it works everywhere
  2. This is probably the only negative with partial classes, namely that you need to include the right units that have the functionality. I have cleaned up the units considerably in v3.0 that is entering testing now, so hopefully this wont be so dispersed in the future
  3. True, this could be nice to have automated. What I usually do is just add an array of TW3CustomForm's to TApplication, and then use the Push() and Pop() to keep track. When you use the array as a stack its much easier and you can move back with a single call: Application.GotoFromByRef(Application.FormStack.Pop(), feToRight); Since its such a small thing we havent really given it much attention, but yes - ill keep that in mind!
  4. IElite is absolutely correct. Sorry if I misunderstood you, I was under the impression that it was the actual showing you had a problem with. Adding an event to the dialog form, or proper methods like IElite does - is the way to go.
  5. If you have designed the loginform via the normal designer (e.g "form2"), then you dont need to register it. All designed forms are auto-registered (if you right-click on the project node in the project-treeview, there is a "view source" option that shows the startup code for you). But, I think you want to use a modal dialog approach. In the Application, there is a modal-dialog function that can show a second form -over the present form. It will also grey out the real mainform (disabled), so it cant be clicked - until you have closed the modal-dialog. So typically you would have two edit-boxes, username + password, and a cancel or "login" button on that form. And the user wont get access to the underlying mainform until he has provided the correct password So in the loginform you would close it by calling: application.HideModal(mrOK); //or mrCancel if it failed And from the main form you would call this to show your modal-form (see code for better description of the params) Application.ShowModal(loginform, nil, nil, procedure (dialog: TW3CustomForm) begin // Write code to execute just after the dialog is showing end, procedure (Dialog: TW3CustomForm) begin // this code fires when modalresult = mrOK end, procedure (Dialog: TW3CustomForm) begin // this code fires when modalresult = mrCancel end);
  6. Javascript doesnt use a VMT, it is based on prototypes which works differently (object in javascript is more like a b-tree node, that in turn can contain any number of sub nodes or name/value pairs). Our model comes on the side of this, and we bypass all the cloning JS developers have to deal with. If you look at the compiled code, you will see that all methods has a hidden "self" parameter. A VMT means that the data of the object and the methods are decoupled, and that the compiler operates with a method-table. Normally in a binary executable, the VMT is maintained at runtime. But since JavaScript is a written, source based language - the VMT is used at compile time to link up the symbols. The reason this is powerful is because it allows inheritance and re-use of existing methods without copying. JavaScript forces you to clone everything (prototypes) which limits how inheritance is dealt with by JS coders (not too elaborate, usually ad-hoc "clone my ancestor" and thats it). Our model dont need cloning. Since we ship the instance data in as the "self" param, we are able to re-use existing methods directly. In our model only the instance data is created and passed around, not the methods and everything else. Had this been a compiled language then yes, then the VMT would be implemented inside the code as part of TObject (actually, just beneath the surface of TObject). But since JS is text based we link up symbols during the compilation. You can watch how this works if you run a program in the browser and set some breakpoints, then inspect the "self" parameter directly: You could say that the JS instance both is a VMT and is sculpted from a VMT. But the sculpting is naturally applied in JS. TObject doesnt magically shape itself so to speak.
  7. lennart

    POST by Sockets

    You probably want to use the ToJSON() function
  8. Thank you for the warm praise! Its taken a long time to make this and the challenges has been many, but like you I firmly believe that object pascal is a better language. I even wrote a kernel in freepascal which says something about the power object pascal has. So I am 100% onboard with your notes on Wirth, a brilliant man and scientist. Great to have you onboard as well, happy hacking buddy!
  9. Hi Dave! Im actually doing this now. Under node, http and https are implemented as separate modules - which are identical. So you are right that you should inherit from TNJCustomServer, but I think you can just copy the whole http-server unit and then make sure it uses https instead. Here are the docs: https://nodejs.org/api/https.html You just have to do a require("https") and import the module. Then define a "class external" for it. If you look at how we import the other modules it should be easy to understand. But - if you can wait for the update Ill try my best to have it ready for you. We were going to wait until the next update (not the one lined up now), but ill see if i can squeeze it into our build for you /Jon
  10. This is taken into account with the framework we are researching / making now. The objects you use to access data act more as "front-ends" to the mechanisms behind it, and just like the filesystem classes the operations are all async. This has the benefit of decoupling the consumer-part (i.e controls + bindings) from the producer aspect. To the consumer parts the database can be resident - or on the other side of the planet, it cares not where the data originates, only that its made available in a format that it can use. A typical middleware entity would be a node.js server that is connected to X number of databases. The client will use the framework and connect to the node.js endpoint, but neither the controls or bindings will have any clue about the data originating from a server. It will simply see a driver and issue calls to it. When the driver (or class) gets the data it will validate and dispatch it via its internal mechanisms. The nice part about this is that, a datasource can be almost anything. As long as someone implements the 3 core classes, it can be anything from a hardcoded file, local database or remote data server for that matter. I will go into more detail about these classes when we are a little closer, but you are quite right that old-school 1:1 endpoints is useless in the new paradigm
  11. lennart

    RTTI demo

    This demo has sadly been broken since version 2.0 I believe. It is a very deeply rooted bug that we sadly cant fix until we update our codegen, which wont happen until at least version 3.2 I believe
  12. lennart


    Really cool! My first thought was that this could make a nice foundation for right-click menus as well!
  13. reader.readAsArrayBuffer(filelist.item(0).slice); First of all "slice" is not a property, but a function. Secondly, item/items is an array, so you access them as: filelist.item[0]. There is a variance between browsers, so i dont think "item" is right, but rather "items".
  14. First, lets look at a couple of facts: The browser does not have a filesystem (*) The browser only allow storage to the cache or database Phonegap does not change the above, but it does remove the limitations on size In version 3.0 of Smart which is just around the corner, this is all about to change for the better (*) Most browsers implements a "fake" sandboxed filesystem. We have support for this, but the way it's implemented in the browser makes it extremely hard to port. You end up with a spaghetti mountain of code that leaves much to be desired. What people do is to store binary data as bin-hex strings in the cache. This has its limitations, and depending on the browser you can store between 5 to 15 megabytes of data there. Again the cache is a sandboxed file, so you never get access to the real files. Its only meant to keep temporary data before you ship it to the server. The units you want to look at for storing data in the cache are: SmartCL.Storage SmartCL.Storage.Local SmartCL.Storage.Cookie SmartCL.Storage.Session SmartCl.Storage contains just a baseclass, but you should add that first to have it available (makes code suggestion faster). As the names imply, each of these provides a standard interface for all the browsers storage mechanisms. The one you want is "local". The session storage is just for temporary storage while the page is active. So when you app closes the data is deleted. Only "storage.local" is persistent. Smart Mobile Studio v3 In the next version we add storage device classes to both web and nodejs. This allows you to store files, examine folders etc. and gives you a full filesystem-api on top of whatever is there. So in the browser we have actually implemented a complete b-tree based storage device from scratch, that saves to the local-storage for you. Under node the same API wraps the exotic and cumbersome node.js filesystem, and allows you to write code that works both in the browser and under node (!) So I think you will love that Uploading files I presume you have X number of files you want to upload in the background right? Well, JS is async so you can just upload all of them at once. The uploading will happen in the background and wont block anything (javascript is non-blocking). But for sake of brewity, you can use a web-worker for it: uses System.Types, System.Types.Convert, SmartCL.WebWorker; type TUploadThread = class(TWebWorkerThread) private procedure InitializeRemobjects; public // This fires when a message is received procedure ReceiveMessage(Data: Variant); override; end; procedure TUploadThread.Execute; begin InitializeRemobjects(); end; procedure TUploadThread.InitializeRemobjects; begin // Do login and everything here // Remember, a webworker or thread runs in its own context so // it will know nothing of your main program end; procedure TUploadThread.ReceiveMessage(Data: Variant); var ByteData: TByteArray; begin // Convert data-string to bytes (note, see BytesToString method in same class) ByteData := TDataType.StringToBytes(Data); // Initialize remobjects for this context, login etc. InitializeRemobjects(); // Do upload here end; Personally I would not bother with a web-worker for this. JavaScript is non-blocking, so you can just call upload on all the files, and they will finish as the work is done. Perhaps add a counter mechanism to make sure they all upload - and to catch errors if they dont. In the above code, once you create it you can use the postmessage to tell the thread what to do -- and the OnMessage() event to catch messages sent back from the worker. This is actually pretty cool because the message stuff works on a lot of tech (for example between frames). So its worth taking a look at. Hope it helps!
  15. Ah, indeed. Have you tried using the effect methods for this? Ill have a look at the code soon and look closer, but I added rotation two updates back
  16. lennart

    PhoneGap and RO

    We need a little more to go on to answere that one. the API uses normal http functions for the browser, but perhaps you could do a dump of the console to see what error you get on the device? In most likelyhood this has to do with the execution policy for the application. You have to tell the phone what you will be using in the manifest for the platform
  17. fAni.Start(nil); FAni.Start(targetcontrol)
  18. Ah sorry, we have changed a couple of names and i probably got those mixed up in this post. There is no point in checking for active in ApplicationStarting because all of this happens in just one session. Even if you open 10 windows they would still not collide. JS is single threaded so there are no locking issues etc. within a browser like you have in native code.
  19. Yes, im afraid that wont work. If you want to push a http request to a node server, then you want to use the http server class in the SmartNJ.* namespace. We have tried to make this as "Delphi like" as possible, although its not always possible (or prudent) to handle everything with classic event handlers under JS. But at least its easy to create a normal http server. Personally I use websocket. Node has full support for it and all browsers supports it. It allows you to send both binary and text messages that is cached properly so they arrive in the correct order. Things like size etc. is dealt with by the stack - and its extremely low latency compared to traditional client/server models. Just make sure you stick to Node.js 6.9.1 since we havent yet reached node.js in our update plans. We started with the visual namespace since that needed the most work, and we are gradually getting closer to node now. There has been a change in how node.js handles events - so "event-emitter" class-defs need to be updated. Its not a huge thing, but newer versions of node will dump out some error warnings that it uses fallback code and that you need to use the new prototypes. This will be updated when we are done with the visual stuff -- Im very excited about node.js myself so im looking forward to brushing up on it.
  20. Why are you using SmartCL.* named units under node.js? SmartCL is the visual namespace and the units prefixed "SmartCL" must never be used in non-visual applications. The only units you can use under node is System.*, SmartNJ.* and the raw NodeJS units. Never mix visual and non visual namespaces. What you are looking for is "System.Time", which provides universal code. Notice that the same unit names exist in different namespaces. System however is fundamental and only contains code that works everywhere
  21. Regarding Windows programs on OSX or Linux. I do this all the time myself:
    Wine works great on Linux and allows you to run most Win32/64 software. On some rare occations you have to copy over some libraries and dll's from windows, but that is like 1 in a million.

    For Macs, use this to install Smart: http://winebottler.kronenberg.org/

  22. I use SMS on mac all the time. Just bottle it in a Wine bottle and off you go: http://winebottler.kronenberg.org/
  23. lennart

    TCP connection.

    Depends on what you are talking about: web html5 or node.js? Node (server) can create just about anything, but websocket is the best solution in my view. So from the browsers perspective: yes, websocket is the only bi-directional communication that is allowed. Websocket also works well as a general tech. It is low latency, handles caching elegantly and nice - and with socket.io you can register keywords and essentially build a protocol very quickly. We had a case where a server written in Delphi using Indy with raw TCP connections actually went down and was unstable over a 3G based network. I introduced a small and efficient WebSocket node.js server for them and the server went from handling 30-50 activities a second to a steady 500. Using a normal node.js cluster like PM2 you can easily handle high volume. NetFlix is written in pure node.js for example, and the push some terabyte a second around the globe
  24. We were not aware that this was the case. I used Smart with XP less than 2 years ago without problems. We have not moved up on our Delphi version (although we are planning to do that), so this must be one of Microsofts magical patches that changes library interfaces to force people away from XP. Not sure what I can say, I will look into it ofcourse, but a strange case indeed!
  25. lennart

    Save Content Dialog

    The node filesystem is wrapped. But right now im implementing filesystem classes, meaning that we will have a unified solution for this. Since storage is so different between node, browser, phonegap and various embedded hardware - it makes sense to create some "driver" like classes that expose a common interface. As for the filesystem units. The System.Filesystem.pas file is presently used by node.js only, but it will be absorbed by the drivers soon. The Filesystem.Memory unit is a fully working filesystem for a "ram disk". That you can also save to the cache. It gives you things like chdir, mkdir, dir, paths etc. etc. for a in-memory device. Then you can save the data to the cache. So this is the "driver" for the browser so to speak. A identical class is being written for nodejs. Both will be async (!) So heads up on that!
  • Create New...