This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-07-26
Channels
- # babashka (16)
- # beginners (38)
- # calva (11)
- # cider (35)
- # clj-kondo (3)
- # clj-otel (3)
- # clojure (28)
- # clojure-europe (11)
- # clojure-gamedev (14)
- # clojure-norway (42)
- # clojure-spec (4)
- # datalevin (10)
- # datomic (2)
- # emacs (8)
- # events (2)
- # fulcro (3)
- # gratitude (5)
- # hyperfiddle (3)
- # kaocha (1)
- # nbb (14)
- # nrepl (12)
- # portal (1)
- # re-frame (5)
- # releases (1)
- # shadow-cljs (36)
- # squint (167)
@mx2000 I always have this question on how to manage Java objects when using Java libs, e.g. libgdx. I wonder how you deal with this: Normally in Clojure we use a map (maybe in an atom) to model the states, use pure functions to transform the map, and push any side-effect, e,g, rendering, to the "edge" of the app. In the example of libgdx, rendering means you would create some Java objects, like Sprite. The problem is, we can't just create tons of Java objects from the state map for every entity for one-time use each render loop, and throw away after, right? That'll be too many objects? So instead, maybe I just keep the Java objects in the state map? but then they are not immutable data so it's inconvenient to transform them with pure functions.
I just try to avoid it as best as possible to use mutable objects. For example I am not using the libgdx Sprite class, but have created an image record which holds just a Texture region (which I don't mutate) https://github.com/damn/gdl/blob/main/src/gdl/graphics/image.clj Also I wrote my own immutable animation class, it's not much code https://github.com/damn/gdl/blob/main/src/gdl/graphics/animation.clj I guess it depends, for example I am using libgdx scene2d ui and just going along with the state management there because there is no alternative for the UI (windows, buttons, etc.)
So that idea of 'too many objects' is missing something. Every single clojure operation on data structures is new-ing up objects. The JVM is incredibly good at collecting objects. The real concern is if the objects being set up and destroyed have a lifecycle that must be followed or if they manage external state like gpu state.
Hmm good point I don't know much about jvm internals. Although immutable data structures are also easier to test and understand. But good to know that doing it with a lot of objects might not be the end of the world
Yeah, quantity of objects that are created and thrown away isn't much of a concern on JDK 11+, and on JDK 8 you can make it fine by setting the GC to use the G1 garbage collector
@U5NCUG8NR thanks for explaining! That's a great point. But still, now that creating Java objects is not a problem, where do you keep them? Do you push them to the edge or do you keep them in state maps? Or something else?
Ideally mutable state won't be the center of your application state
if they have non-final members (or final members that are references to mutable objects) then yes
that's not to say never use mutable stuff, just not to represent your primary game state.
sprites and files and other resources have to be managed somehow and it's easiest to hold them in clojure data structures
just don't have your actual state of game objects be mutable
Got it. Last time I interoped with some Java lib, it was so awkward! But I need to give it another try. Thank you both!
To second Joshua’s comments, I maintain a ccg written in clojure. the game state is an atom, and the whole codebase is peppered with swap!
calls. It makes debugging and testing a pain, and ruins any attempts at threading or functional style. It’s exactly the wrong way to write clojure lol