Jump to content


  • Content count

  • Joined

  • Last visited

  • Days Won


lynkfs last won the day on July 13

lynkfs had the most liked content!

About lynkfs

  • Rank

Profile Information

  • Gender
  • Location

Recent Profile Visitors

428 profile views
  1. lynkfs

    loading images

    it is a cors error Access to Image at 'file:///C:/Users/...../res/object.jpg' from origin 'null' has been blocked by CORS policy: Invalid response. Origin 'null' is therefore not allowed access. would be very interested in getting a solution for this too
  2. lynkfs


    There are various object-types implemented in Smart and javascript. According to aSmartbook (4.1.6) Smart has a super-parent class 'Object' which is parent to TObject and to JObject. TObject is the ancestor for all rtl descendants and JObject is the parent for external classes. Javascript of course has its own object structure. I was wondering if it would be possible to derive usable components from any or all of these various object types. Deriving a new class therefore depends on who (which object type) is going to be chosen as ancestor. By way of demo, a TSet class is created with methods to maintain a list of values and to make it usable in Venn-diagrammatic operations (intersect, union, difference, subset etc). TSet is implemented 3 times: as a component derived from TObject, as a component derived from a jsArray and as a component derived directly from the javascript object (jsObject). These implementations differ internally quite a bit, but usage in a Smart app is exactly the same. A) TSet derived from TObject type TSet = class public Constructor Create; virtual; Procedure add(Item: Variant); Procedure remove(Item: Variant); Function contains(Item: Variant) : boolean; Function union(&Set: TSet2) : TSet2; Function intersect(&Set: TSet2) : TSet2; Function difference(&Set: TSet2) : TSet2; Function isSubset(&Set: TSet2) : boolean; Function length : integer; Procedure Print; values : array of variant; end; implementation Constructor TSet.Create; begin inherited Create; end; Procedure TSet.add(Item: Variant); begin If values.IndexOf(Item) < 0 then values.add(Item); end; and usage var set1 : TSet := TSet.Create; set1.add(1); set1.add(2); set1.add(3); set1.print(); // => 1 2 3 nothing special about this B ) TSet derived from a javascript array (see) Javascript has a different inheritance mechanism using prototypes. type TSet = class public Constructor Create; virtual; Procedure add(Item: Variant); ... FHandle: variant; end; implementation Constructor TSet.Create; begin inherited Create; asm function Set() { this.values = []; } Set.prototype.add = function(value) { if(!~this.values.indexOf(value)) { this.values.push(value); } }; @FHandle = new Set(); end; end; Procedure TSet.add(Item: Variant); begin FHandle.add(Item); end; usage is the same. C) TSet derived from the ultimate ancestor : jsObject type TSet = class public Constructor Create; virtual; Procedure add(Item: Variant); ... FHandle: variant; end; implementation Constructor TSet.Create; begin inherited Create; asm function Set() { this.lastIndex = 0; } Set.prototype.add = function(value) { for (var property1 in this) { if (typeof this[property1] === 'number') { if (this[property1] == value) { break; } else { Object.defineProperty(this, this.lastIndex.toString() , { value: value, configurable: true, writable: true, enumerable: true }); //console.log(this.lastIndex); this.lastIndex++; break; }; }; }; //console.log(Object.getOwnPropertyNames(this)); }; @FHandle = new Set(); end; end; Procedure TSet.add(Item: Variant); begin FHandle.add(Item); end; again usage is the same I don't think these last 2 approaches have much of a practical application, and while it works, there is no obvious advantage to stray away from TObject (and there may be hidden disadvantages as well). Curiosity kills the cat. Project code with full implementations and demo (not much to see, uses console)
  3. lynkfs

    architecture 911

    Interesting things sometimes happen unexpectedly. In this case by combining several unrelated posts : rapid prototyping webworkers and flow based programming compiled procedures In reverse order : the last post described a short-cut to produce webworkers on the fly. The middle post describes an alternative architecture where a network is constructed out of webworkers and messagechannels, and the first post covers a possible take on rapid prototyping. The subject of this post is that prototyped business processes can be graphed as well moreover, these business process graphs can be mapped as a network of workers which can be of the on-the-fly internal type. That makes for a crazy architecture, but with some advantages. For interested parties, see document here. It also has a link to see this in action.
  4. lynkfs

    Scroll bar bug

    This has happened since day 1, somewhere in 2013, so it has occurred a lot. Every time it happens I heave a mental *sigh* and then move on. I'm sure it has something to do with my setup (Win10 on MacOs via Boot Camp), although none of the other programs on this platform have this behaviour - SMS only. A comparison with Paulo's setup or video ☺️ might shed some light if there are more people effected.
  5. lynkfs

    Scroll bar bug

    in my install (win10) the ide source code pane auto-selects text and auto-scrolls every time the scrollbar (hor or vert) is dragged with the mouse or when the arrows on the scroll bars are clicked
  6. lynkfs

    Scroll bar bug

    annoying isn't it. I've been wanting to ask if there is a solution for that for a long time. Maybe there is ? @jarto
  7. lynkfs

    compiled procedures

    Found that after all it actually is possible to create webworkers inline/on the fly from compiled procedures without resorting to writing js-code and without having to specify an external javascript file either. See edited previous post
  8. lynkfs

    webworker demos fail

    The webworker demos (featured demos) seem to fail ? @jarto
  9. lynkfs

    compiled procedures

    When creating webworkers, the choice is to either set up a separate project for each worker (see featured demo's), or create separate text files with the webworkers code. Another alternative is to create workers from a string : myWorker := createWorker(#" onmessage = function(e) { console.log(e.data); } "); function createWorker(workerFunc: string) : variant; var newworker: variant; begin asm const blob = new Blob([workerFunc], {type: 'application/javascript'}); const url = URL.createObjectURL(blob); @newworker = new Worker(url); end; result := newworker; end; hybrid coding The main advantage though is that creating workers can be done in the main project, no need to switch back and forth Note : unfortunately I don't see a possibility to use the 'toString()' method here to generate webworker strings from compiled pascal functions. Edited : Actually it is possible to create webworkers inline/on the fly from compiled procedures without resorting to writing js-code. As an example the TestFunc procedure below is injected into a new Worker as compiled js. No need to specify an external worker file either. //create a new variant var Dummy : variant := TVariant.CreateObject; //give it an anonymous function Dummy.TestFunc := lambda (e:variant) function test(a: integer): integer; begin result := inc(a); end; asm console.log((@e).data); end; var a:integer := 1; a := test(a); asm console.log(@a); end; end; //convert function TestFunc to a string and create worker from it var temp: string; asm @temp = ((@Dummy).TestFunc).toString(); end; WWTry := createWorker( 'onmessage = ' + temp ); the resulting worker code : onmessage = function (e) { var a = 0; function test(a) { return ++a; }; console.log((e).data); // 'testing' a = 1; a = test(a); console.log(a); // '2' } and executing worker : //execute worker WWTry.postMessage('testing'); results as expected in 'testing' '2'
  10. lynkfs

    WebWorkers and Flow Based Programming

    mmm, works fine with FF at my place. (FF Quantum 61.0 64 bit on Win10) FF is usually better than Chrome in this respect, it handles local file-based webworkers as well as server-based ones, where Chrome silently fails on local file based webworkers. But I'm surprised by this SecurityError. Googling this gives lots of references to FF being resentful to blocked cookies ? Lots of other reactions as well, so I'm not sure. Might try sandboxing (hamburger-help) to see if that makes a difference As a side-note : I know Edge (and Safari) don't support SharedWorkers yet, so this demo won't work on those browsers. However there is no particular reason to use sharedWorkers either, it works as well with just normal dedicated workers. See here demo with normal webworkers, which should work on any browser. For interest sake let me know if that makes any difference (by the way projectcodes available for your perusal on www.lynkfs.com/Experiments/FBP/FBPWW.sproj (sharedWorkers) and .../FBP2 (dedicated workers)
  11. WebWorkers and Flow Based Programming It has been a while since I got as excited as I was when I read J.Morrison's book "Flow-Based Programming: A New Approach to Application Development - 2nd edition". This post is not meant to give an overview of FBP, but if someone is interested, the first edition of his book is available online for free. FBP utilises independantly running processes which are wired together in an assembly line type of arrangement. The main advantages are that each process runs on demand rather than on availability, components can easily be re-wired to implement changes in requirements and there are possibilities for extensive component re-use. I was in the process of porting this framework to Smart, when I realised that javascript and concurrently running processes is not an easy match. Basically all js code in the browser executes in the same thread, and time-slicing mechanisms like setTimeout (used in the framework I was porting) doesn't enable real concurrent processing. However there are 2 exceptions to escape the single-threadedness : IFrames and webworkers. Both implement runtimes separate from the main thread and have their own heap, stack and message handling mechanism. The similarities between the FBP and shared webworker specs are (more than) striking, so this post is about having a go at implementing FBP using webworkers. Technically - processes (fbp) can be implemented through shared webworkers - connections between processes (fbp) can be implemented using channels (webworker to webworker, buffered) - ports (fbp) can be implemented using ports (webworker) - reading/writing of information packets's (fbp) can be implemented using messaging (webworker) - information packet handling (fbp) can be implemented using the transferable interface (webworker) The demo chosen is a variation of the 'Galaxy Clock' project in the featured-demo's section. The variation being that the 'single motor' driving the 3 hands of the clock (hr, min, sec) is replaced by 3 separate 'motors', each driving one of the hands and each one operating in its own thread. The architecture of this demo : a scheduler webworker receives the current local time when a button is clicked in the main program. It transfers the time-elements to each of the other web-workers through the channels created. These other webworkers in their turn update the main project at appropriate intervals. The result of this rather peculiar architecture. The hr/min/sec displays are purposely not synchronised and are all running at 10x normal clock-speed.
  12. lynkfs


    I probably misunderstood the original post. I can see that Lazarus and pas2js could produce a result from the native framework's source code. After all, it doesn't use or need any of the RTL units. Interesting.
  13. lynkfs


    I suppose this was bound to happen. Not sure if I should object to this or not, after all I put source code in the public domain Meant though for Smart users only. Could we have a secure place somewhere which we can use to share code for the Smart community only ?
  14. lynkfs

    Tw3TabControl's OnPrepareTab ?

    your OnPrepareTab code is executed when the 'PrepareTab' event eventually eventuates. By that time your 1-3 loop has finished and str will have the value of the last looping. Your second block seems correct to me
  15. lynkfs

    Rapid prototyping - 3

    This is the third of three mini posts on (my take on) rapid prototyping, to explore possibilities of how to easily generate prototypes of complex systems. Step 3 is to model the business processes. I'm using a standardised demo-business (EU-rent) and graphs to model concept, data and processes. Every node represents a main business process and at least one of the edges represent the starting event. Some business processes occur many times per day, some only once in a while. So for instance EU-rent, which has 1000 branches in multiple countries, will have a process to "open up a new branch". However this will occur so infrequently that it probably isn't very interesting to model. The process associated with 'booking' on the other hand will occur many times per day and deserves a better look. Modelling this process is done by taking the booking node and finding all connected nodes 1 layer deep. The "Make a booking" process (making a reservation) therefore touches "customer" (issues/makes a reservation), car-group (which type of car), car-model (optionally specific model), rental-period (start/end) and branch (availability of cars in period). The process might read something like a customer decides to make a reservation and starts an online process or tells it to an available cle The clerk/system asks the costumer for his/her ID The system checks if the customer is a person who has had contact with EU-Rent. If he or she exists, verifies that the customer has not been blacklisted otherwise creates a new EU-rent customer/driver The system checks the period desired, the pick-up branch, the dropoff branch, countries planned to visit and, optionally, the car group or the car model desired. It verifies that the period is correct, that there is no overlap with other reservations of the customer and the availability of the specified car group or car model for the period indicated. If the customer has neither specified a car group nor a car model, he will be assigned a car belonging to the cheapest group. If the customer has specified a car model but there are no cars available of that model, a car of the same group will be assigned. The result of steps 1, 2 and 3 is available here. I've assigned the 'make booking' process from this step to the 'issues'-edge (clicking on the word 'issues' generates a process image and process description). Also included are descriptions to some nodes and edges from step 1 and the example customer data from step 2 (dbl-click customer node). The input-files used are graph-sentences (step 1) as in customers make bookings bookings specify car groups rental cars are grouped in car groups and node specific data (step 2) like [{"id":1,"first_name":"Aubry","last_name":"Hanne","email":"ahanne0@multiply.com","gender":"Female"}, {"id":2,"first_name":"Callida","last_name":"Lendrem","email":"clendrem1@youtube.com","gender":"Female"}, {"id":3,"first_name":"Guinevere","last_name":"Scarrisbrick","email":"gscarrisbrickj@acquirethisname.com","gender":"Female"}] with some additional descriptions of nodes and edges (step 3) I like the way the main graph is used as a menu, as suggested before , but this could be easily transformed into a proper menu as well. The resulting prototype is obviously not a finished application, but can be used to finalise specs.