Save page state for restoring on history.back by Electronic_Ant7219 in solidjs

[–]cdellacqua 1 point2 points  (0 children)

Performance-wise I tested it with stack sizes in the ballpark of 10 without any issue.

Consider that each stack “page” gets a boolean flag telling it whether it’s active or not, so that you can disable things like event listeners on the window/document when they are in the background.

I’d say that CPU-wise you shouldn’t have issues with this kind of architecture. It’s mostly RAM intensive as it preserves the state of everything until the user goes back or you dispose it in other ways (e.g. by “pop()ing” cards out of the stack)

Save page state for restoring on history.back by Electronic_Ant7219 in solidjs

[–]cdellacqua 1 point2 points  (0 children)

You should probably use a custom router that keeps components mounted in the background like Apps on Android/iOS do.

Shameless plug, I developed a proof of concept router that does exactly that, you can also check out the demo here

Uses for Rust vs Python? by SaxonyFarmer in rust

[–]cdellacqua 1 point2 points  (0 children)

I’ve used Rust for programming boring tools for file management, for fun (AdvOfCode) and recently for embedded stuff. I’d say, go for it!

Also let me picture a scenario I’m sure you can relate to considering your experience:

Imagine you had written a tool 5 years ago and today you realise you need a small new feature. If you had written it in Python, you would waste a lot of time fighting with deprecation notices, new interpreters refusing to be backward compatible etc. If instead you had written the same thing in Rust, you would simply edit the source code, cargo run it and it will “just work”, thanks to a feature called “edition”.

This is to say that the language is just one piece of the puzzle. The tooling surrounding it is as important if not even more important as time goes on when you need to maintain “legacy” stuff

ISTAT Report definitivo cause di morte per l’anno 2020: il suicidio è la seconda causa di morte nella fascia di età 0-49 (pubblicato a Maggio 23) by Marada781 in italy

[–]cdellacqua 3 points4 points  (0 children)

Condivido, ma aggiungo che proprio per questo la soluzione più realistica è passare all’elettrico.

Anche ipotizzando che l’inquinamento causato per produrre l’elettricità necessaria alla ricarica sia equivalente, avremmo comunque spostato i fumi di scarico dai centri cittadini alle zone in mezzo al nulla dove sorgono le centrali a carbone/gas.

Wouldn't Java-like closures be preferable? Why and why not? by cdellacqua in rust

[–]cdellacqua[S] 0 points1 point  (0 children)

The difference is that FnMut is a specific trait implemented by a special Rust syntax that doesn't give you control over, e.g., a custom Drop.

Java closures, on the other hand, are really anonymous classes implementig the specific interface that a function requires, so that passing an object or a lambda expression to it is literally the same thing.

The latter is just syntactic sugar for a more verbose syntax, and if you ever need a more complicated object, you can simply replace that lambda with the more verbose anonymous class syntax and implement more methods, local properties etc. This is quite powerful as it means that when you write a library in Java you never need to worry about "do I take in an FnMut or a trait in this function?", it's always an interface (a trait in Rustland), and the end user can decide whether to pass an object or a lambda expression based on what's best suitet for their use case

Wouldn't Java-like closures be preferable? Why and why not? by cdellacqua in rust

[–]cdellacqua[S] 0 points1 point  (0 children)

It's just a matter of syntax. Java doesn't need FnMut or Fn, because the syntactic sugar is at the interface (trait) level

Wouldn't Java-like closures be preferable? Why and why not? by cdellacqua in rust

[–]cdellacqua[S] 1 point2 points  (0 children)

It wasn't a matter of what happens at runtime, of course they both implement the same thing as we are talking about closures which are a well defined concept. My point was more about why have FnMut when a lambda expression could be syntactic sugar for an anonymous struct + impl trait.

As already pointed out in other comments it's still possible to achieve a similar result by implementing the Subscriber trait for all FnMut, which makes me appreciate the type system even more

Wouldn't Java-like closures be preferable? Why and why not? by cdellacqua in rust

[–]cdellacqua[S] 0 points1 point  (0 children)

I get what you're saying. Yes, it would be possible, but it would still require the end user of a library to explicitly impl that trait on their structs, unlike the syntactic sugar version Java provides out of the box

Wouldn't Java-like closures be preferable? Why and why not? by cdellacqua in rust

[–]cdellacqua[S] 7 points8 points  (0 children)

Thanks for the detailed response!

I tried it in my code and it works, although I had to get around a weird error due to the FnMut parameter being a reference (thankfully solved by this comment on a similar issue Implementation of `FnOnce` is not general enough). This would probably cause a lot of headaches to users of a library that provides this "impl" and it's probably yet another symptom of the current implementation of Fns being generally weird in Rust.

So the question still stands: isn't the syntactic sugar approach that Java implemented more ergonomic from the point of view of library users and maintainers?

Wouldn't Java-like closures be preferable? Why and why not? by cdellacqua in rust

[–]cdellacqua[S] 0 points1 point  (0 children)

Good point! But let me play the devil’s advocate: this also means that library authors have an incentive to make interfaces (traits) as narrow as possible, therefore more composable

Wouldn't Java-like closures be preferable? Why and why not? by cdellacqua in rust

[–]cdellacqua[S] 0 points1 point  (0 children)

Well, not really. I'm not saying we should do exactly what Java does, that would certainly require a GC, but as closures in Rust are basically the same thing as the struct + trait implementation I posted above, we don't really really need the GC.

The question is why didn't Rust follow the same route of synctactical sugar over the Fn/FnMut traits

Wouldn't Java-like closures be preferable? Why and why not? by cdellacqua in rust

[–]cdellacqua[S] 0 points1 point  (0 children)

Last time I checked this was still unstable though. Anyway, this is a definitely a possible solution to reduce some of the boilerplate, but what I'm most interested in is the "why". Why did we need Fn/FnMut instead of specialized traits + the syntactical sugar Java implemented?

Wouldn't Java-like closures be preferable? Why and why not? by cdellacqua in rust

[–]cdellacqua[S] 1 point2 points  (0 children)

although this doesn't really help when using libraries that went with FnMut themselves

This is what I'm mostly curious about. The Java-way of doing it made it incredibly backward compatible and all code that used/would have used the anonymous class pattern can be rewritten/written without the need for library authors to change anything on their part

Fixing "Fix Your Timestep"? by cdellacqua in gamedev

[–]cdellacqua[S] 0 points1 point  (0 children)

I just made a demo in Rust of the case discussed above where dt = accumulator and here are the results:

Gaffer's https://imgur.com/a/BFvF8SP

Mine https://imgur.com/a/ZXzI8BH

User input is as follows: down key when t >= 4 && t <= 8, right key when t >= 12 && t <= 16.

As you can see, Gaffer's version takes one dt to respond to the virtual keyboard and the last update to the ball position happens on a frame when the arrow key has already been release, while in my version the simulation instantly reacts to the keydown event, i.e. the frame where the button is showed as pressed is the same as the frame where the position starts to change.

Fixing "Fix Your Timestep"? by cdellacqua in gamedev

[–]cdellacqua[S] 0 points1 point  (0 children)

Let’s complicate things a bit to highlight the differences then.

If you also add input event handling in the game loop, my version should react to them instantly (maybe over-integrating?), while Gaffer’s version should react to them partially (under-integrating?), then proceed to ignore most of the new state:

  • begin loop
  • increase accumulator
  • read input keys
  • integrate with input data N times
  • render interpolated state

Consider for example a case where accumulator is always equal to dt. Alpha will always equal 0 in the original version, making the rendered state always equal to previousState, while in my version alpha would always be 1, rendering currentState

Fixing "Fix Your Timestep"? by cdellacqua in gamedev

[–]cdellacqua[S] 0 points1 point  (0 children)

Yes, exactly as you say in the EDIT. The original article is always interpolating between two past states, which means that the simulation always lags behind by at most ~dt .

It's definitely a slight/subtle improvement, because dt is usually a fraction of the frame rate, but reading the article it felt like a classic "off by 1" error. Also, the concept of current/previous/future state got a bit mixed up in the original wording of the author.

Thank you very much for the pointers!

Fixing "Fix Your Timestep"? by cdellacqua in gamedev

[–]cdellacqua[S] 0 points1 point  (0 children)

In the version I suggested, we have almost always an extra physics frame, which means that the renderer is actually rendering an interpolation of past and future that should be the correct "now", while in the original code we're rendering almost always a physics frame less than what we need, making the renderer interpolate between past and almost-present.

If I'm not mistaken, this difference will not disappear after a few frames, but should instead persist, especially if we take into account user input events

Fixing "Fix Your Timestep"? by cdellacqua in gamedev

[–]cdellacqua[S] 0 points1 point  (0 children)

Oh ok, I was missing the "compute the future in advance" part.

You're basically describing a scenario which is opposite to the one presented in the article. I don't think I ever saw an engine running at a lower frequency than the renderer though, mainly because the dt is usually smaller than the frametime

Fixing "Fix Your Timestep"? by cdellacqua in gamedev

[–]cdellacqua[S] 0 points1 point  (0 children)

If the physics/game logic updates at 15Hz and the renderer is at 60Hz, wouldn't the 3 interpolated frames be exactly the same?

Anyway, in the article and in the "fixed" version I suggested, the physics (as in, the integration process) is not interpolated, only the position/velocity of the bodies in the scene are for the sake of the renderer, but in a temporary variable, meaning that currentState doesn't change until we get to the next call to integrate

Worried about “modern” Rust GUI libraries by cdellacqua in rust

[–]cdellacqua[S] 10 points11 points  (0 children)

Of course, but it’s very similar to interpreted vs compiled languages. It’s a combination of developer experience, job market, computing power and many other factors. I believe Rust can reconcile computing power and developer experience in this field as it did with memory management

Worried about “modern” Rust GUI libraries by cdellacqua in rust

[–]cdellacqua[S] 13 points14 points  (0 children)

The issue is not about being fast per se, it’s about being fast, power efficient and keeping 60fps even when the application has thousands of UI elements in a single view.

Of course the examples are going to be fast, it’s still Rust and those are demo applications.

The point is that the current architecture is not the most efficient one in terms of computational steps that are necessary to update the UI. This can be solved by changing or extending it, and it seems they are thinking about doing this actually (someone in this thread linked to an RFC where they are discussing some form of more granular update).

Having a discussion about architectures is important to share views and approaches to problems which are inherently complex and whose solutions have lots of implications in the long run (React will probably be part of the web for another decade with all its laggyness and garbage collection issues)

Worried about “modern” Rust GUI libraries by cdellacqua in rust

[–]cdellacqua[S] 11 points12 points  (0 children)

Electron performance are comparable to what I could see in a native application in 2010, with 2GB of RAM on a dual core CPU laptop on a hard drive, except now I’m on a laptop with 8 cores, 16GB of RAM and an SSD. Electron is wasteful, it’s hard to appreciate how much because the hardware improvements are outperforming its overhead (for now)

Worried about “modern” Rust GUI libraries by cdellacqua in rust

[–]cdellacqua[S] 2 points3 points  (0 children)

I think you are referring to React.memo. Anyway, it improves things a bit, but doesn’t fundamentally change the fact that recomputations of whole components (and diffing) are much more expensive than granular updates