Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Brightscript port of QRCode Generator #110

Open
wants to merge 18 commits into
base: master
Choose a base branch
from

Conversation

ahwayakchih
Copy link
Contributor

@ahwayakchih ahwayakchih commented Jun 6, 2022

Hi,

I created an initial port of JS version of qrcode-generator to BrightScript (used to write apps for Roku devices).

Would you be interested in merging this into main qrcode-generator repo? Or should it be a separate "fork" project?

I'll probably keep updating code with time (and use in my apps). I think i'll extract some parts to separate components or merge them into main QRCode component. ot sure yet :).

In any case, this works ok as is. To make a full test you'd have to have a Roku device at hand, but "core" functionality (generating QRCode data, plus turning it into ASCII-like render, same as with JS version) can be tested using brs.
I included test and package.json that will use @hulu/roca test runner - all you need is to have a node.js installed (or running in container or VM :)).

npm install
npm test

brs (used by roca) implements only parts of BrightScript and SceneGraph APIs. Generating QRCode with it is A LOT slower than when running it on Roku device, so don't be scared if test runs over 6 seconds. On device it generates data in less than 600ms and turns it into PNG image in another ~350ms (or prints to console as ASCII in ~45ms).

Here's output from npm test command:

bash-5.1$ npm test

> [email protected] test
> roca


QRBitBuffer
  ✓ can be created
  ✓ has `getBuffer` method
  ✓ has `getLengthInBits` method
  ✓ has `pushBit` method
  ✓ has `put` method
QRCode
  QRCode
    ✓ should generate correct UTF8 text data

  QRPrinter
    ✓ should generate correct UTF8 string from exsiting QRCode
    ✓ should return correct UTF8 string from exsiting QRCode

QRMath
  ✓ glog is working
  ✓ gexp is working

  10 passing (5s)

Here's console output from Roku device running example channel:

06-08 16:11:00.943 [beacon.signal] |AppLaunchInitiate ---------> TimeBase(0 ms)
06-08 16:11:00.943 [beacon.signal] |AppCompileInitiate --------> TimeBase(0 ms)
06-08 16:11:00.945 [scrpt.cmpl] Compiling 'QRCode Generator', id 'dev'
06-08 16:11:00.951 [scrpt.load.mkup] Loading markup dev 'QRCode Generator'
06-08 16:11:00.957 [scrpt.unload.mkup] Unloading markup dev 'QRCode Generator'
06-08 16:11:00.966 [scrpt.parse.mkup.time] Parsed markup dev 'QRCode Generator' in 14 milliseconds

------ Compiling dev 'QRCode Generator' ------
06-08 16:11:01.021 [scrpt.ctx.cmpl.time] Compiled 'QRCode Generator', id 'dev' in 55 milliseconds (BCVer:0)
06-08 16:11:01.022 [scrpt.proc.mkup.time] Processed markup dev 'QRCode Generator' in 0 milliseconds
06-08 16:11:01.025 [beacon.signal] |AppCompileComplete --------> Duration(81 ms)
06-08 16:11:01.030 [ui.frm.plugin.running.enter] Entering PLUGIN_RUNNING for dev
06-08 16:11:01.030 [beacon.signal] |AppLaunchInitiate ---------> TimeBase(0 ms)
06-08 16:11:01.231 [beacon.signal] |AppSplashInitiate ---------> TimeBase(200 ms)
06-08 16:11:01.875 [beacon.signal] |AppSplashComplete ---------> Duration(644 ms)

06-08 16:11:01.969 [scrpt.ctx.run.enter] UI: Entering 'QRCode Generator', id 'dev'
------ Running dev 'QRCode Generator' runuserinterface ------
Init: TestScene
Creating QRCode took:           529ms
Creating PNG took:              361ms
QRCode image created as:        tmp:/a76a272ab306a3d6b1c0ddeed6a44e37.png
█▀▀▀▀▀▀▀█▀▀██▀██▀█▀▀▀██▀▀▀▀▀▀▀█
█ █▀▀▀█ █▄▀█▄▀██▄▄▀ ▀▀█ █▀▀▀█ █
█ █   █ █▄▄▀▄▀█ ▄▀▀█ ██ █   █ █
█ ▀▀▀▀▀ █▀█ ▄ █▀▄▀█ ▄ █ ▀▀▀▀▀ █
█▀█▀▀█▀▀▀▄ ▀██▄█▄ ██▄██▀██▀█▀▀█
███ ▄ █▀█▀▀▀▀▄▀  █▀ ▄▄█ ▄▄█▀▀▄█
█  █▄▀█▀▀  █▀▀█ ▀█▄▄███▄▄█ ▀█▄█
█ ▀▄█▀ ▀▄▄▀▄█ ▀ ▀▄▄▀ ██ █▀▀▀  █
█ ▄█  ▀▀  ▄ ▀ ▄  ▀▄█  ▀█ ▀██ ██
█▀█▀▄█▀▀▀▀█ ▄  ██▄▄▄█▀█▀▀█▀ ▄██
██▀▀██▀▀▀ █▄▀█▀▄█ █▀▀▀ ▀▀▀▀ ███
█▀▀▀▀▀▀▀█ ▄ ██ █ ▄▀ ▀ █▀█  ▄ ▄█
█ █▀▀▀█ █▄▀  ▀█▀▄ ▄ █ ▀▀▀ ▀▀  █
█ █   █ █ █▀▄█ ▄ █▀▄█  █▀▄▄ █ █
█ ▀▀▀▀▀ █▀▀█ █ ▄▄▄ ▀▀ ▄█▄█ █ ██
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
Printing to console took:       45ms
06-08 16:11:08.863 [beacon.signal] |AppExitInitiate -----------> TimeBase(7832 ms)
06-08 16:11:08.864 [beacon.header] __________________________________________
06-08 16:11:08.864 [beacon.report] |AppLaunchInitiate ---------> TimeBase(0 ms)
06-08 16:11:08.864 [beacon.report] |AppSplashInitiate ---------> TimeBase(200 ms)
06-08 16:11:08.864 [beacon.report] |AppSplashComplete ---------> Duration(644 ms)
06-08 16:11:08.864 [beacon.report] |AppExitInitiate -----------> TimeBase(7832 ms)
06-08 16:11:08.865 [beacon.report] |AppExitComplete -----------> Duration(1 ms)
06-08 16:11:08.865 [beacon.footer] __________________________________________

Please not that the spacing between blocks depends on the font. In local Terminal i see no spacing, but in this PR's description i see some - depends on font config used on GitHub.

And here's a screenshot from the same run:
screenshot

Mostly straightforward port of JavaScript version of QRCode Generator
created by Kazuhiko Arase.

Some of the components are split a bit differently and some internal
names are changed.
Public API stays similar, changed only to match "Roku-way"
of doing things: `typeNumber` and `errorCorrectionLevel` are specified
through field values, `make` function should be called after `addData`
calls.

Only core QRCode handling is ported. Plus printing "ASCII" version to
either string or console log.
It was called just from a single place inside `QRCode` anyway.

Instead of calling `isDark` for every point, get all `modules` array
first and then just access items directly.

Test run using `brs` before change:
```
real	0m20,842s
user	0m0,215s
sys	0m0,089s
```

Test run using `brs` after change
```
real	0m6,401s
user	0m0,223s
sys	0m0,081s
```
First try to run on Roku device discovered multiple issues:
- fix shadowed variable and use of uninitialized var reported by linter
- prefix unused variables reported by Roku
- fix Rooibos test
- change `type` to `typeNumber` variable, `type` is used by Roku
- rename `QRData_Number` to `QRData_Numeric` directory name
- rename `QRData_8BitByte` to `QRData_Byte` directory name
- moved common parts of test to `QRCodeTest` component
- moved `QRPrinter` out of `QRCode` directory, as it's not a "core" code

Also: QR is generated super fast on Roku (even on Roku Express).
      A LOT faster than running with `brs` (<600ms vs >6s :D)!
It generates PNG image and puts it on screen.
Name test components start with `test` word to make them less likely
to be confused as required part of the library.

Stop exposing QRMath functions from `QRCode` component. That was for
testing only, so move that to `TestQRCode` component.
Not necessary for test channel, but for potentially turning it into
full-blown downloadable component library.
Instead of adding them to the `TestQRCode`, which made test runs
to be a lot longer than necessary.
No need to setup whole env, if we just want to run some basic tests
in CI pipeline.
Rooibos warned that it will auto-extend from `Group` which is renderable
and we do not want that in this case.
This allows to still set different `width` and `height` if needed,
and better matches loading regular images.
It's a bit more involved now, but only if one needs that.

Removed `toLog`, since it was just a `toString` with `print` called.
Removed `toString`, exposing `toASCII` directly instead.

Now printing QRCode can be done either through calling the function,
or similarly to `QRPoster`: by setting `qrcode` or `text` field.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant