GithubHelp home page GithubHelp logo

Comments (4)

joaodasilva avatar joaodasilva commented on April 30, 2024

Hi Arjix, thanks for the contribution!

Agreed that Window.js should also have setInterval and clearInterval.

Window.js doesn't preload a Javascript file, other than the native builtins, so this approach doesn't work right now. I don't think we want to add a preloaded Javascript file because it will take a bit longer to load compared to native code, so it would make every startup a bit slower than it could be.

Some comments about the code you wrote:

  1. The global object in Window.js is globalThis. See these docs:

https://windowjs.org/doc/global
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis

So you should just do

globalThis.setInterval = function(callback, interval) { ... }

  1. Date.now() is not a stable time source; for example, it may go back in time during daylight savings days (two times a year), or if the user adjusts the clock, or for any other reason.

Clocks for intervals like in setInterval should use a monotonic time source, that only advances forward and always at a constant rate. A good source for that in Javascript is performance.now():

https://developer.mozilla.org/en-US/docs/Web/API/Performance/now

So you could just take a timestamp when a callback is registered, and then compare its timestamp to performance.now() when firing callbacks.

  1. setInterval() may be called from inside a callback! So the for loop in fireIntervals() may end up mutating g.intervalState.intervals while it's still looping (same for clearInterval). This may cause strange bugs like skipping ahead when a callback gets removed.

--

I guess this change will really have to go in the C++ code. Here's a pointer to the table of setTimeout callbacks if you want to give this a try:

std::unordered_map<uint32_t, v8::Global<v8::Function>> timeouts_;

See also how it's implemented:

api->task_queue()->Post(timeout, [=] {

The task_queue is used internally to run Javascript callbacks once on every frame. I think that's the ideal rate to call setInterval: each callback gets called at most once per loop, and as fast as frames are getting pushed to the screen.

Let me know if you'd like to make that change, or if someone else should implement this.

from windowjs.

ArjixWasTaken avatar ArjixWasTaken commented on April 30, 2024

I am not an experienced c++ dev, so I bet if I go ahead and do it myself I will introduce a bug or smth.
And that would place more work on you in order to troubleshoot it.

So yeah, someone else should implement this.

from windowjs.

joaodasilva avatar joaodasilva commented on April 30, 2024

Sure, np. You can always have your own module with globals and import it manually in your programs:

import './path/to/stuff.js';

Just put anything you'd like in the globalThis object.

from windowjs.

joaodasilva avatar joaodasilva commented on April 30, 2024

Some context to implement this in C++.

  • all Javascript code, and all of the API calls, execute in the main thread
  • all of the Javascript context is owned by the Js class, in js.cc
  • js.cc is mainly responsible for wrapping the v8 Isolate and Context classes, and loading Javascript modules
  • all of the Javascript APIs are registered via js_api.cc (which delegates bigger APIs to js_api_canvas.cc, js_api_file.cc, etc.)
  • js.h has a TaskQueue [1]. This is just a list of C++ functions to be called later. This TaskQueue is valid as long as the Js instance is valid too.
  • finally, the Js instance and the TaskQueue instance are owned by main.cc. See the main loop there to see when tasks execute.

To implement setInterval:

  • have a map of pending callbacks, similar to timeouts in [2]
  • when the API gets called, generate the next ID and put an entry in that map
  • to schedule the execution, post a task to the task queue like here: [3]
    (note that TaskQueue takes the timeout in seconds, not milliseconds)
  • TaskQueue will execute that task only once. After executing the Javascript code, check if the setInterval ID is still valid; if it is, schedule the task in the TaskQueue again to run it again in the future
  • if clearInterval is called, then just remove the callback from the map. The task in the TaskQueue should check that the ID is still valid before executing the callback.

Searching with grep for the SetTimeout implementation will find most of the places that need some code (probably js_strings.h is enough, and registering the API in js_api.cc)

[1]

TaskQueue* task_queue_;

[2]
std::unordered_map<uint32_t, v8::Global<v8::Function>> timeouts_;

[3]
api->task_queue()->Post(timeout, [=] {

from windowjs.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.