• Are there any limits on javascript object usage?

    i have an object which looks like

    var chars = {
    80: new Uint8Array([
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0xff,0xff,0xff,0xff,0xfe,0x00,0x00,
    0x03,0xff,0xff,0xe0,0x00,0x00,0x02,
    0xff,0xfe,0x00,0x00,0x00,0x0b,0xff,
    0xe0,0x7f,0xff,0x40,0x7f,0xfe,0x07,
    0xff,0xfe,0x02,0xff,0xe0,0x7f,0xff,
    0xf4,0x1f,0xfe,0x07,0xff,0xff,0x81,
    0xff,0xe0,0x7f,0xff,0xf8,0x1f,0xfe,
    0x07,0xff,0xff,0x42,0xff,0xe0,0x7f,
    0xff,0xe0,0x2f,0xfe,0x07,0xff,0xf4,
    0x07,0xff,0xe0,0x00,0x00,0x01,0xff,
    0xfe,0x00,0x00,0x00,0x7f,0xff,0xe0,
    0x00,0x00,0x7f,0xff,0xfe,0x07,0xff,
    0xff,0xff,0xff,0xe0,0x7f,0xff,0xff,
    0xff,0xfe,0x07,0xff,0xff,0xff,0xff,
    0xe0,0x7f,0xff,0xff,0xff,0xfe,0x07,
    0xff,0xff,0xff,0xff,0xe0,0x7f,0xff,
    0xff,0xff,0xfe,0x07,0xff,0xff,0xff,
    0xff,0xe0,0x7f,0xff,0xff,0xff,0xfe,
    0x07,0xff,0xff,0xff,0xff,0xe0,0x7f,
    0xff,0xff,0xff
    ]),
    // ... and so on, right now up to 23 attributes like the one above
    

    i experienced some weird behaviour when i raise the sizes of the Uint8Arrays (like 50-100 elements more) --> out of memory

    for the object above (including all 23 attributes) and some functions i get

    { "free": 4054, "usage": 1046, "total": 5100, "history": 2928,
      "stackEndAddress": 536959096, "flash_start": 134217728, "flash_binary_end": 375472, "flash_code_start": 134234112, "flash_length": 393216 }
    

    and

    >E.getSizeOf(chars);
    =287
    

    i am certainly not expecting a out of memory, even if the the charsobject would be double the size than before

  • i did some further testing, there seems to be an upper limit for the javascript variable size (i hit it with objects or arrays), right now i just splitted my data into usable parts

    is the max size somewhere documented?

  • You might be running out due to the intermediate representation. Pretend you're a parser and look at

    var x = new Uint8Array(["blah","blah",....])

    Before we can evaluate that, we have to read in that bit between the []'s, which creates a standard array (1 or 2 jsvars per item). Then that gets passed to the Uint8Array constructor, which returns something much smaller. Plus it needs to store the big blob of text while it parses it...

    So while your final structure may be small (I think it comes out to 12 bytes per jsvar? Or does it use flat strings for more efficiency now?), you can end up with higher memory usage while processing it.

  • Put it in level 0, code it and junk it up... that way - on upload - each junk is sent to Espruio and processed, and only the final result is kept. For example:

    var cs = {};
    var hex="0123456789abcdef";
    function ld(cs,p,s) { console.log(p);
      var l=s.length, v=cs[p]=new Uint8Array(l/2), i=0, j=0;
      console.log(p);
      while (j<l) {
        v[i] = (hex.indexOf(s.charAt(j))<<4)|hex.indexO­f(s.charAt(j+1));
        i++; j+=2;
      }
    }
    console.log("uploading...");
    ld(cs,"80","fffffffffffffffffffffffe0000­03ffffe0000002fffe0000000bffe07fff407ffe­07fffe02ffe07ffff41ffe07ffff81ffe07ffff8­1ffe07ffff42ffe07fffe02ffe07fff407ffe000­0001fffe0000007fffe000007ffffe07ffffffff­e07ffffffffe07ffffffffe07ffffffffe07ffff­ffffe07ffffffffe07ffffffffe07ffffffffe07­ffffffffe07fffffff");
    ld(cs,"81","fffffffffffffffffffffffe0000­03ffffe0000002fffe0000000bffe07fff407ffe­07fffe02ffe07ffff41ffe07ffff81ffe07ffff8­1ffe07ffff42ffe07fffe02ffe07fff407ffe000­0001fffe0000007fffe000007ffffe07ffffffff­e07ffffffffe07ffffffffe07ffffffffe07ffff­ffffe07ffffffffe07ffffffffe07ffffffffe07­ffffffffe07fffffff");
    ld(cs,"82","fffffffffffffffffffffffe0000­03ffffe0000002fffe0000000bffe07fff407ffe­07fffe02ffe07ffff41ffe07ffff81ffe07ffff8­1ffe07ffff42ffe07fffe02ffe07fff407ffe000­0001fffe0000007fffe000007ffffe07ffffffff­e07ffffffffe07ffffffffe07ffffffffe07ffff­ffffe07ffffffffe07ffffffffe07ffffffffe07­ffffffffe07fffffff");
    ld(cs,"83","fffffffffffffffffffffffe0000­03ffffe0000002fffe0000000bffe07fff407ffe­07fffe02ffe07ffff41ffe07ffff81ffe07ffff8­1ffe07ffff42ffe07fffe02ffe07fff407ffe000­0001fffe0000007fffe000007ffffe07ffffffff­e07ffffffffe07ffffffffe07ffffffffe07ffff­ffffe07ffffffffe07ffffffffe07ffffffffe07­ffffffffe07fffffff");
    ld(cs,"84","fffffffffffffffffffffffe0000­03ffffe0000002fffe0000000bffe07fff407ffe­07fffe02ffe07ffff41ffe07ffff81ffe07ffff8­1ffe07ffff42ffe07fffe02ffe07fff407ffe000­0001fffe0000007fffe000007ffffe07ffffffff­e07ffffffffe07ffffffffe07ffffffffe07ffff­ffffe07ffffffffe07ffffffffe07ffffffffe07­ffffffffe07fffffff");
    ld(cs,"85","fffffffffffffffffffffffe0000­03ffffe0000002fffe0000000bffe07fff407ffe­07fffe02ffe07ffff41ffe07ffff81ffe07ffff8­1ffe07ffff42ffe07fffe02ffe07fff407ffe000­0001fffe0000007fffe000007ffffe07ffffffff­e07ffffffffe07ffffffffe07ffffffffe07ffff­ffffe07ffffffffe07ffffffffe07ffffffffe07­ffffffffe07fffffff");
    ld(cs,"86","fffffffffffffffffffffffe0000­03ffffe0000002fffe0000000bffe07fff407ffe­07fffe02ffe07ffff41ffe07ffff81ffe07ffff8­1ffe07ffff42ffe07fffe02ffe07fff407ffe000­0001fffe0000007fffe000007ffffe07ffffffff­e07ffffffffe07ffffffffe07ffffffffe07ffff­ffffe07ffffffffe07ffffffffe07ffffffffe07­ffffffffe07fffffff");
    ld(cs,"87","fffffffffffffffffffffffe0000­03ffffe0000002fffe0000000bffe07fff407ffe­07fffe02ffe07ffff41ffe07ffff81ffe07ffff8­1ffe07ffff42ffe07fffe02ffe07fff407ffe000­0001fffe0000007fffe000007ffffe07ffffffff­e07ffffffffe07ffffffffe07ffffffffe07ffff­ffffe07ffffffffe07ffffffffe07ffffffffe07­ffffffffe07fffffff");
    ld(cs,"88","fffffffffffffffffffffffe0000­03ffffe0000002fffe0000000bffe07fff407ffe­07fffe02ffe07ffff41ffe07ffff81ffe07ffff8­1ffe07ffff42ffe07fffe02ffe07fff407ffe000­0001fffe0000007fffe000007ffffe07ffffffff­e07ffffffffe07ffffffffe07ffffffffe07ffff­ffffe07ffffffffe07ffffffffe07ffffffffe07­ffffffffe07fffffff");
    ld(cs,"89","fffffffffffffffffffffffe0000­03ffffe0000002fffe0000000bffe07fff407ffe­07fffe02ffe07ffff41ffe07ffff81ffe07ffff8­1ffe07ffff42ffe07fffe02ffe07fff407ffe000­0001fffe0000007fffe000007ffffe07ffffffff­e07ffffffffe07ffffffffe07ffffffffe07ffff­ffffe07ffffffffe07ffffffffe07ffffffffe07­ffffffffe07fffffff");
    ld(cs,"90","fffffffffffffffffffffffe0000­03ffffe0000002fffe0000000bffe07fff407ffe­07fffe02ffe07ffff41ffe07ffff81ffe07ffff8­1ffe07ffff42ffe07fffe02ffe07fff407ffe000­0001fffe0000007fffe000007ffffe07ffffffff­e07ffffffffe07ffffffffe07ffffffffe07ffff­ffffe07ffffffffe07ffffffffe07ffffffffe07­ffffffffe07fffffff");
    ld(cs,"91","fffffffffffffffffffffffe0000­03ffffe0000002fffe0000000bffe07fff407ffe­07fffe02ffe07ffff41ffe07ffff81ffe07ffff8­1ffe07ffff42ffe07fffe02ffe07fff407ffe000­0001fffe0000007fffe000007ffffe07ffffffff­e07ffffffffe07ffffffffe07ffffffffe07ffff­ffffe07ffffffffe07ffffffffe07ffffffffe07­ffffffffe07fffffff");
    ld(cs,"92","fffffffffffffffffffffffe0000­03ffffe0000002fffe0000000bffe07fff407ffe­07fffe02ffe07ffff41ffe07ffff81ffe07ffff8­1ffe07ffff42ffe07fffe02ffe07fff407ffe000­0001fffe0000007fffe000007ffffe07ffffffff­e07ffffffffe07ffffffffe07ffffffffe07ffff­ffffe07ffffffffe07ffffffffe07ffffffffe07­ffffffffe07fffffff");
    ld(cs,"93","fffffffffffffffffffffffe0000­03ffffe0000002fffe0000000bffe07fff407ffe­07fffe02ffe07ffff41ffe07ffff81ffe07ffff8­1ffe07ffff42ffe07fffe02ffe07fff407ffe000­0001fffe0000007fffe000007ffffe07ffffffff­e07ffffffffe07ffffffffe07ffffffffe07ffff­ffffe07ffffffffe07ffffffffe07ffffffffe07­ffffffffe07fffffff");
    console.log("-----> console.log(\"ld 'still' there)\"");
    console.log((typeof ld === "undefined") ? "ld gone" : "ld 'still' there");
    delete ld; // <------ purging ld() function after it has done its duty... ;-)
    console.log("-----> console.log(\"ld gone)\"");
    console.log((typeof ld === "undefined") ? "ld gone" : "ld 'still' there");
    console.log("uploaded cs ld part");
    function onInit() {
      console.log("-----> dump():");
      dump();
      console.log("-----> console.log(cs):");
      console.log(cs);
      console.log("-----> console.log(\"ld gone)\"");
      console.log((typeof ld === "undefined") ? "ld gone" : "ld 'still' there");
      console.log("-----> console.log(process.memory():");
      console.log(process.memory());
    }
    

    What is taken advantage here is the fact that Espruino goes right to work on upload: it does not just parse the code, but execute it right away when a statement is complete... this is @Gordon's only option to live with as little as memory as a lot of MCs provide.

    As you can see from the additional code - the standalone console.log()s and the ones inonInit(), especially the one withdump();- is that your source code is not around anymore... only the executed result is there. Oupload it has been executed because it is in level 0... similar as you enter commands in the console (left pane) of the Espruino Web IDE. Actually, it is not just *similar* but *the very same*. You can verify that by copy-pasting statement by statement into the console and you will get the same result. (For the functions you best copy-paste all lines of the function at once.) You can push it even further and purge/delete theld()` load function after it has done its job.

    Console output:

    >reset();
    =undefined
     _____                 _
    |   __|___ ___ ___ _ _|_|___ ___
    |   __|_ -| . |  _| | | |   | . |
    |_____|___|  _|_| |___|_|_|_|___|
              |_| http://espruino.com
     1v86 Copyright 2016 G.Williams
    >echo(0);
    uploading...
    80
    80
    81
    81
    82
    82
    83
    83
    84
    84
    85
    85
    86
    86
    87
    87
    88
    88
    89
    89
    90
    90
    91
    91
    92
    92
    93
    93
    -----> console.log("ld 'still' there)"
    ld 'still' there
    -----> console.log("ld gone)"
    ld gone
    uploaded cs ld part
    =undefined
    >
    

    Now you enter in console onInit() and you get something like that as console output, which shows that your cs (chars) object is loaded and your source and load function ld are gone...

    >onInit()
    -----> dump():
    var cs = {
      "80": new Uint8Array([255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 0, 0, 3, 255, 255, 224, 0, 0, 2, 255, 254, 0, 0, 0, 11, 255, 224, 127, 255, 64, 127, 254, 7, 255, 254, 2, 255, 224, 127, 255, 244, 31, 254, 7, 255, 255, 129, 255, 224, 127, 255, 248, 31, 254, 7, 255, 255, 66, 255, 224, 127, 255, 224, 47, 254, 7, 255, 244, 7, 255, 224, 0, 0, 1, 255, 254, 0, 0, 0, 127, 255, 224, 0, 0, 127, 255, 254, 7, 255, 255, 255, 255, 224, 127, 255, 255, 255, 254, 7, 255, 255, 255, 255, 224, 127, 255, 255, 255, 254, 7, 255, 255, 255, 255, 224, 127, 255, 255, 255, 254, 7, 255, 255, 255, 255, 224, 127, 255, 255, 255, 254, 7, 255, 255, 255, 255, 224, 127, 255, 255, 255]),
      "81": ...
      "82": ...
      "83": ...
      "84": ...
      "85": ...
      "86": ...
      "87": ...
      "88": ...
      "89": ...
      "90": ...
      "91": ...
      "92": ...
      "93": new Uint8Array([255, ..., 255])
     };
    var hex = "0123456789abcdef";
    function onInit() {
      console.log("-----> dump():");
      dump();
      console.log("-----> console.log(cs):");
      console.log(cs);
      console.log("-----> console.log(\"ld gone)\"");
      console.log((typeof ld === "undefined") ? "ld gone" : "ld 'still' there");
      console.log("-----> console.log(process.memory():");
      console.log(process.memory());
    }
    -----> console.log(cs):
    {
      "80": new Uint8Array([255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 0, 0, 3, 255, 255, 224, 0, 0, 2, 255, 254, 0, 0, 0, 11, 255, 224, 127, 255, 64, 127, 254, 7, 255, 254, 2, 255, 224, 127, 255, 244, 31, 254, 7, 255, 255, 129, 255, 224, 127, 255, 248, 31, 254, 7, 255, 255, 66, 255, 224, 127, 255, 224, 47, 254, 7, 255, 244, 7, 255, 224, 0, 0, 1, 255, 254, 0, 0, 0, 127, 255, 224, 0, 0, 127, 255, 254, 7, 255, 255, 255, 255, 224, 127, 255, 255, 255, 254, 7, 255, 255, 255, 255, 224, 127, 255, 255, 255, 254, 7, 255, 255, 255, 255, 224, 127, 255, 255, 255, 254, 7, 255, 255, 255, 255, 224, 127, 255, 255, 255, 254, 7, 255, 255, 255, 255, 224, 127, 255, 255, 255]),
      "81": ...
      "82": ...
      "83": ...
      "84": ...
      "85": ...
      "86": ...
      "87": ...
      "88": ...
      "89": ...
      "90": ...
      "91": ...
      "92": ...
      "93": new Uint8Array([255, ..., 255])
    }
    -----> console.log("ld gone)"
    ld gone
    -----> console.log(process.memory():
    { "free": 4850, "usage": 250, "total": 5100, "history": 481,
      "stackEndAddress": 536959096, "flash_start": 134217728, "flash_binary_end": 375472, "flash_code_start": 134234112, "flash_length": 393216 }
    =undefined
    > 
    

    Btw, what are you using this mass data for? ...image / font? ...odd length: 143 bytes each block...

  • thx i will try that soon

    the data is for a grayscale font, one part stands for one char(anti aliasing, 2bpp, 4 colors), "80" is for "P" and so on

  • Ic... cool! ...I'm sure it is for the e-paper / e-ink display. I c 2: you do not like the 'ausgefranst' (frayed) characters rendered by Espruino built-in vector fonts...

    ...are there versions with touch screen available you would know of?

    ...is there a reason not to use array of arrays? ...first array charCode / ASCII value indexed... with offset of 32 (0x20)?

  • code works like charm, i will try to change my conversion workflow (includes parsing a C file and creating javascript)

    ...are there versions with touch screen available you would know of?

    not that i know of, i am not sure it would make sense, the refresh cycle time goes not well with input reaction time expectations, if you google around you will find e.g. an interview (german) with a representative from pervasivedisplays who talks about touch and e-paper

    ...is there a reason not to use array of arrays? ...first array
    charCode / ASCII value indexed... with offset of 32 (0x20)?

    well i use only some characters not a complete set and some number gaps (e.g. abcdefghi but no j, and so on), so i need some address mapping , hmm i will try it with a complete font, maybe it fits into the memory (depends on width/height, will be interesting to test it out)

  • Glad to hear you having fun... there is enough code grief around...

    interview in German

    even google.de could not get me there... (US 'Zensur'). What is the url?

    some address mapping...

    You got that already... may be you have to develop your own Graphics.drawString()... or override the method where the bitmap is looked up.... or you do the transformation before and not supplying the full matrix for the backing font... (I do not know if the Graphics object can handle that).

    parsing a C file and creating javascript

    Absolutely... create modules for each character... and you could even think of simple compression - before load or even for draw - and forget drawString() all together: just mapping memory to memory, and if you make it compiled, it will be very fast... (needs of course to put sufficient meta data into each char definition... in byte string or as object with properties). I'm working on a ui core with ui elements extension that work exactly in such way: require("base").addAndDelete(require("c8­0"),"c80") - load module into cache, use its data - delete it from cache. Get yourself an (serial) FlashEEPROM mounted for the font modules... then you can do it all dynamic with variable driven require(moduleName); (or you use (one of the) free pages on Espruino FlashEEPROM... and use - of course - something different than require(...) for loading the raw data...).

    In your code:

    // ----- pull in chars base and desired characters
    var cs = require("chars").ld("0123456789ABCM");
    

    chars.js module:

    // chars.js module
    exports =
    { hex:"0123456789abcdef"
    , ld: function( // load font bit map for characters to support
          cs // chars as string for which font bit map has to be loaded
        ) {
      var csl = cs.length // length cs string
        , cdx             // idx to individual char in cs
        , cmn             // character font bit map module name 
        , cspec           // char spec, for example:
                          //   { id: "80" // id
                          //   , w: 23    // used width in pixel
                          //   , h: 56    // used height in pixel
                          //   , x: 5     // offset from left in px (char spacing)
                          //   , y: 3     // offset from top in px (placing w/in line height)
                          //   , s: 143   // size of bit map in bytes (uncompressed
                          //   , cbm: "ffffff....." // coded bit map as string (?compressed)
                          //   }
        , cbm             // coded bit map as string
        , bma             // bit map array
        , nibCnt          // nibbles count (length of cbm string)
        , ndx             // nibble index
        , bdx             // byte index into Uint8Array
        ;
      for (cdx = 0; cdx < csl; cdx++) {
        cmn = "c" + cs.charCodeAt(cdx);
        cspec = require(cmn);
        this[cspec.id] = { w: cspec.w, h: cspec.h, x: cspec.x, y: cspec.y
                         , bma: (bma = new Uint8Array(cspec.s)
                         };
        nibCnt = (cbm = cspec.cbm).length;
        bdx = 0; ndx = 0;
        while (ndx < nibCnt) { // not supporting compression yet... :(
          bma[bdx] =   (this.hex.indexOf(cbm.charAt(ndx))<<4)
                     | this.hex.indexOf(cbm.charAt(ndx+1));
          bdx++; ndx += 2;
        }
        Modules.removeCached(cmn);
      }
    };
    

    Example character module: P - 80

    exports = // ----- P ----- c80.js -----
    { id: "80"
    , w: 23
    , h: 56
    , x: 5
    , y: 3
    , s: 143
    , cbm: ""ffffff001122ffff"
    }
    

    ...and I'm sure you'll do better than that... ;-) NB: code only partially verified :|

    PS: you can test the code 'mechanics' without FlashEEPROM card: just add the requires for the characters statically before loading chars.

    require("c80");
    ...
    ...
    var cs = require("chars").ld("0123456789ABCM");
    ...
    
  • Sorry for the delay - I've been away this past week... But yeah, it'll be storing the data in text form and the standard array form before it gets into a Uint8Array.

    To get the data in quickly and easily you could use base64, then atob and E.toUint8Array to convert the data. That should all be done without needing to allocate any data, and base64 is pretty compact.

    You can use btoa on your PC to encode the data, or I made a file converter website: http://www.espruino.com/File+Converter

  • thanks for all the help

    @allObjects the example with modules looks like a good way to provide the function for all Espruino users, i will look into that (combined with that base64 hint from @Gordon)

  • @JumJum, thanks, gives me what I need to know. Fazit: statische Anzeige, Ausdruck elektronisch dargestellt...

  • @allObjects if you looking for low power displays (but usable for faster refresh cycles) take a look at sharp memory lcd

  • I can definitely recommend the memory LCDs. There's an Espruino driver for them, they work really well, and don't need many external components.

    I just wish they were cheaper to buy, but compared with epaper they're still pretty good :)

  • ... and there is (will be) a round one for the puck ;-) http://sharpmemorylcd.com/0-96-inch-memo­ry-lcd.html

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

any limits on javascript object or Uint8Array usage?

Posted by Avatar for MichaelPralow @MichaelPralow

Actions