Jump to content


  • Content count

  • Joined

  • Last visited

  • Days Won


lennart last won the day on August 5

lennart had the most liked content!

1 Follower

About lennart

  • Rank

  • Birthday 09/21/1973

Contact Methods

  • Website URL

Profile Information

  • Gender
  • Location
    Vestfold, Norway


  • Company name
    The Smart Company AS
  • Sector
    Information technology
  • Position
    Lead developer

Smart Mobile Studio

  • Edition

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. lennart

    "inline" Keyword?

    Inline is interesting but we have no immediate plans for it. The way JS contexts work makes sub-procedures and anonymous procedures more or less the same thing. Macros in the C/C++ style or templates is much more interesting. Procedure TForm1.Something; var x, y, z: integer; procedure SomethingElse(const CB: TProcedureRef); begin if assigned(CB) then CB(); end; begin SomeThingElse( procedure () begin writeln("Not sure we need inline under JS"); end); end;
  2. lennart

    memo lines ?

    Look at the definition Memo.Lines is defined as an array of string. So you can do: for item in w3memo1.lines do begin writeln(item); end;
  3. lennart


    Awesome! Very interested in this! Cant wait to see more!
  4. lennart

    Tw3Sprite - flash problem

    TW3Sprite is not really meant for traditional game sprites like you and me know them. The first thing that comes to mind is wrapping the image-change in a TW3Dispatch.RequestAnimationFrame(), but there is no guarantee that it wont flicker. For "real sprites" I added a DrawTile() and DrawPart() functions in TW3Canvas. If you imagine a tile grid over a picture, say 32x32 pixels per tile, you can draw a spesific tile very quickly to the canvas. It will calculate the row/column based on the tile-size + tile number. So if you draw tile #32, and the tileset picture is 640 x 480 pixels in size, and the tile is 32x32 pixels, you get: rows := height div tileheight; if rows * tileheight < height then inc(Rows); cols:= width div tilewidth; if cols * tilewidth < width then inc(cols); RowEntry := tilenumber div rows; ColEntry := tilenumber mod cols; RowEntry := RowEntry * TileHeight; ColEntry := ColEntry * TileWidth; The above is done automatically for you, so you just need to count the tile# and use that. Here is an article predating the canvas update, but it gives some insight into where we took the ideas from. https://jonlennartaasenden.wordpress.com/2014/01/27/codef-for-smart-mobile-studio/
  5. lennart

    parseInt question

    I was about to write that the snippet simply copies 2 by 2 hex characters and then converts that to an integer number. In pure pascal it would be a bit messy since pascal's StrToInt doesnt support hex (unless prefixed by $). ASM sections are very much needed, they might not be pretty (not too fond on them myself) but there are some fundamental code sections that would never work if we used pascal only. Speed is also a factor to keep in mind, especially for procedures that you will call many times. But you seem all set so i'll leave you to it! Happy coding!
  6. lennart

    Compilation Question: Format command

    Use resourcestrings in a separate unit, easier
  7. Omg.. i am now a shade of pink. I am so sorry about that, ill have it removed asap!
  8. lennart

    TMemo-like Control with Colored Text?

    Hi David! The good news is that all the ordinary rules of html apply, everywhere. So you can for example set the text of a line with inline html (see listbox.items.add or listbox.add depending on version): ’<p style=«background-color: #ff0000»>hello red</p>’ The DOM will recognize this and inject it as is, which is both easy and fun. If you need more elaborate styling you might want to check the SmartCL.%css% units. There is a global stylesheet where you can inject full styles and then use that instead of inline styling. let me know if you run into difficulty
  9. lennart

    Save tw3image to desktop?

    This we found our culprit: procedure TW3CanvasFont.ReadFontInfo; begin end; It doesnt parse the font information and expects to inherit from the container. This works fine on visual controls (TW3GraphicControl) but will naturally be a problem on a raw device context
  10. lennart

    Save tw3image to desktop?

    Hm, this is strange. The exposed "font" property of TBitmap is just a proxy, it relays the font property of TW3Canvas - which is the HTML5 canvas for that context. The canvas/bitmap stuff was a bit tricky because under HTML5 its completely opposite of what we have in Delphi or FPC. We are used to creating a bitmap and then attaching a TCanvas to that bitmap -- but in html5 the canvas holds the data while the context delegates access. But then again, everything in the JS world is topsy turvey at times. Its a bit like going from ordinary physics to quantum physics - you can throw your old notions of solid reality out the window This should be easy enough to fix. The legacy unit was initially something I made for a demo earlier, but since it made porting delphi code easier I figured it could also help others. This is why it has escaped the more hard-core testing that we did on the visual components and low-level namespaces. But ok, lets fix this and get it out Also -- there is no need to go via the handle, the old "font" text property was just renamed to "FontStyle" since that's what it does. We had to do this to make room for TFont.
  11. lennart

    Save tw3image to desktop?

    Have a look in SmartCL.System, scroll down to line 1113, there you will find the class TW3URLObject: TW3URLObject = static class public class function GetObjectURL(const Text, Encoding, ContentType, Charset: string): string; overload; class function GetObjectURL(const Text: string): string; overload; class function GetObjectURL(const Stream: TStream): string; overload; class function GetObjectURL(const Data: TAllocation): string; overload; class procedure RevokeObjectURL(const ObjectUrl: string); // This cause a download in the browser of an object-url class procedure Download(const ObjectURL: string; Filename: string); overload; class procedure Download(const ObjectURL: string; Filename: string; const OnStarted: TProcedureRefS); overload; end; This should make it easier. Also look at TAllocationHelper, which targets TAllocation - used by TMemoryStream and TBinaryData (system.memory.buffer).
  12. lennart

    Errors when working on my Node.JS server project

    In all probability "something" in the project causes the background compiler to go bananas and kills the thread. This has happened in some rare cases when inline JS is used, but i think we have seen 2-3 of these over 8 years, so very rare. Like Jarto says its impossible to figure out "what" causes this from a stack-trace, that only tells is the entrypoint in the IDE which in all likelyhood is not the culprit. We really want to find out what this is so we can get rid of the behavior, so if you can share the code that would really help!
  13. lennart

    SQL Server Connection

    You dont do threads in JS unless its exceptionally important. Server side you delegate work between processes, as in shell-execute and then passing work to it via node's message channel. So lets say you have a heavy duty server and for some reason need threading, you would write the thread code as a completely separate node application. In the server you would then start the process on demand and then pass the socket-handle (the request object) to the newly created process. This is the same as threading but easier to build up on since you are using the outer layer of shell/os. You can also use web-workers, which are threads, but still need to pass the request object (or whatever else you need) via messages, so most people just spawn a new process and pass in the request to handle it. So a low down would be: Server accepts request Server creates a process for handling the request Server pass the http/websocket request to the process process does whatever its designed to do Server is notified when the process is done or have failed So its more or less the same. I should underline that the whole point of ASYNC coding is to avoid threading as much as possible, but i realize that this mindset can be a bit alien for beginners in Smart Pascal - so you can evolve with it safely as you get more into it When it comes to DB then yes, absolutely - but im not sure there is a SQL server wrapper for it. But node supports just about every DB engine out there. Its one of the engines I will write a connection class for in our next 2 updates. SQLite is already there (actually we have 2, one via node and one we compiled to asm.js ourselves), mariadb (mysql), MSSQL, Firebird and oracle is on my list. Simply google if node.js can do it -- if it can, we can do it also. But when importing modules like this, someone have to write a wrapper. Its like delphi when using a dll file, you have to write defines for the methods etc. and load in the module before using it. So its fairly identical to how you work with external code in delphi. Visit NPM and have a look, there are quite a bit to pick from https://www.npmjs.com/search?q=SQLServer
  14. lennart

    & before procedure name

    The & is as you say, just to make it not collide with reserved names
  15. lennart


    Good write! Also make sure the IE patch is included when using this code, since "array.indexOf()" doesnt exist in pre Edge browsers. "inherited" also has no meaning when using JObject etc. because they are compiled without a VMT and are thus without inheritance in the object pascal/C++ way of thinking