Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411508 Posts in 69374 Topics- by 58429 Members - Latest Member: Alternalo

April 26, 2024, 08:31:35 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)The happy programmer room
Pages: 1 ... 226 227 [228] 229 230 ... 279
Print
Author Topic: The happy programmer room  (Read 678516 times)
InfiniteStateMachine
Level 10
*****



View Profile
« Reply #4540 on: February 18, 2017, 02:20:02 PM »

Well at a conceptual level the new state doesn't represent the delta. It's an entirely new state with the operation applied.

But what you're describing is pretty close to how it's implemented under the hood.

An example would be a linked list of 5 nodes. If you modify the middle node and are returned a new list with the modified node applied, internally what you have is a linked list of 5 nodes where the 2 outer nodes are actually the same memory addresses as the original but the middle one and adjacent to middle nodes (due to needing pointer fixup) are new.

I think this is one of the main reasons these types of languages have to be GC'ed. Keeping track of that would be pretty rough I think.
Logged

pelle
Level 2
**



View Profile WWW
« Reply #4541 on: February 19, 2017, 12:29:18 AM »

I  have used Clojure (and ClojureScript) a bit in the last few years. It is all built around data-structures like that, so even if it looks like code is doing very expensive operations modifying some read-only structure and returning a new read-only structure, what happens under the hood is some magic shuffling of pointers so memory is shared and not too much CPU is wasted allocating new things.

It is not something I have ended up using all the time, but for some small hacks now and then. It is very nice to not have that constant worry about some state somewhere not being what it ought to be, and just simple functions that can be tested by passing in some data and see that they return the correct things. I like to think it has really helped me think better about how to design APIs even when coding C++ or JavaScript, although when the standard-library of a language is not built around everything being read-only (and if you want some performance) it can not be applied 100%.
Logged
oahda
Level 10
*****



View Profile
« Reply #4542 on: February 19, 2017, 05:53:54 AM »

So I don't know if this makes sense to anybody (or if anybody can be bothered reading through the console output here) but using the serialisation for the editor that packs metadata alongside the fields when compiling the editor version of the code, as opposed to the release build which will just turn this into regular fields with no bloat, now seems to be fully working, identifying changes to the struct since the last serialisation (change in name, type and value, and it doesn't matter if the order of the members of the struct changed). Woop!



Through the use of templates, I'm getting more metadata than I actually store in runtime memory: only the name of the field and the value actually end up in the runtime footprint (as well as a pointer to these; see next paragraph).

Only grumpiness now is that my approach is a bit heavier than it could've been, because of the inconsistent padding that happens to C++ structs, so I can't do it as low-level as I first had in mind (can't use offsetof() to get around it in this case, unfortunately), forcing me to put the data on the heap instead of the stack, which irks me, but after all it's only in the editor and not in the release build, so we'll have to see how it works out.

In this example, I actually just deserialised the bytes into a completely different struct, and while I can't imagine it would make any difference, I'm now going to attempt actually doing it to the same, but modified, struct from a reloaded dynlib. c:
Logged

JWki
Level 4
****


View Profile
« Reply #4543 on: February 19, 2017, 06:51:47 AM »

I'm getting really icky to start a general purpose engine project again but then I remember how much daunting shit that entails and I still kinda wanna do it again.

Fuck.

Also this post is terribly misplaced in this thread.
Logged
JWki
Level 4
****


View Profile
« Reply #4544 on: February 19, 2017, 09:15:34 AM »

To make up for my last post, this code makes me happy (-ish):

Code:
RUNTIME_API void Main(Platform* platform)
{
printf("Hello Runtime\n");


auto self = platform->dynamicLib.Load("runtime");
typedef void(*MainFunc)(Platform*);
auto selfMain = reinterpret_cast<MainFunc>(platform->dynamicLib.LoadFunction(self, "Main"));
selfMain(platform);

return;
}

Since dynamic library loading seems to be hot atm, this loads and calls itself recursivly!
Fortunately the platform layer stops loading modules after 32 loaded instances so it didn't crash my machine when I tried it out.
Logged
oahda
Level 10
*****



View Profile
« Reply #4545 on: February 19, 2017, 02:07:43 PM »

And so it all comes together: structs are serialised, then modified, then hotloaded back, and the deserialiser successfully deals with it!



Since dynamic library loading seems to be hot atm, this loads and calls itself recursivly!
Fortunately the platform layer stops loading modules after 32 loaded instances so it didn't crash my machine when I tried it out.
Haha, good job. Definitely an interesting thing to test and see how the OS deals with it.

I'm getting really icky to start a general purpose engine project again but then I remember how much daunting shit that entails and I still kinda wanna do it again.

Fuck.
Sorry ;__;
Logged

zilluss
Level 1
*



View Profile
« Reply #4546 on: February 20, 2017, 01:48:55 AM »

On another note, I'm happy because I finally managed to figure out how to do vsync with SDL2. All you had to do was use a renderer, give it the right tags and use RenderPresent.

The last time I checked, SDL2 didn't support VSYNC in windowed mode, so I switched to GLFW. Did this change recently? I'd like to give SDL2 another go.
Logged

@zilluss | Devlog  Hand Point Right
JWki
Level 4
****


View Profile
« Reply #4547 on: February 20, 2017, 02:35:11 AM »

Haha, good job. Definitely an interesting thing to test and see how the OS deals with it.

Well the OS just doesn't, it'll just recurse and recurse and recurse and recurse...
My win32 platform layer internally keeps track of all loaded libraries tho and will only allow 32 to be loaded in.

Also, nice work on the serialization, though I never really liked having to wrap fields, I find it a bit too intrusive, but as long as it works for you that's great!
I have successfully fought my engine urges by remembering that you get most of the fun parts of writing an engine when writing a game from scratch, without most of the not so fun parts.
Logged
oahda
Level 10
*****



View Profile
« Reply #4548 on: February 20, 2017, 02:50:44 AM »

Well the OS just doesn't, it'll just recurse and recurse and recurse and recurse...
My win32 platform layer internally keeps track of all loaded libraries tho and will only allow 32 to be loaded in.
Aaah, okay. Well, that still answered the interesting question!

Also, nice work on the serialization, though I never really liked having to wrap fields, I find it a bit too intrusive, but as long as it works for you that's great!
Yeah, it feels slightly dirty, but it's only for the fields that I want to expose in the editor anyway and not all of them, and I ended up just overloading arrow and dereference operators to make the wrapper work essentially like a pointer, so the syntax isn't unfamiliar, and as far as I've understood, the macro expansion that compiles into the final build will be absolutely zero-cost.

I have successfully fought my engine urges by remembering that you get most of the fun parts of writing an engine when writing a game from scratch, without most of the not so fun parts.
Yeah, lots of it will just be gruelling routine. Having fun right now tho since the stuff I'm playing around with ATM (hotloading and serialisation) is quite new to me. Always nice to learn more! c:
Logged

bauer
Level 1
*


Codes games & makes music


View Profile WWW
« Reply #4549 on: February 20, 2017, 04:29:46 AM »

The last 3-4 weeks I've been re-creating our engine for Super Sportmatchen with the main intention of having clean multi-platform support from the start. My aim has also been to learn how to program in a more "lean C" kind of way instead of the heavy C++ way of coding that I've mostly been doing. As someone mentioned recently, it is a lot more fun to code when you're aware of the bits and bytes instead of hiding it all behind crazy libs and templates! For me that means no STL (especially no std::string and std::map), no SFML/SDL, no crazy class hierarchies etc. It's all basic but highly functional C-type code, compiled with a single .bat file as a single translation build (~1s compile time!).

I wish I could tell my teenage self to not listen to the OOP teachings and "don't be afraid of the bytes and pointers" or something. Beer!

Did you watch Handmade Hero? Tongue

I personally prefer a healthy balance in between either extreme school of thought. Tongue Just try to make the best choices for each particular situation, taking every aspect into consideration. c:

That sounds like a healthy approach. Even though I guess everybody comes from one of the two directions originally so everybody has a certain baseline way of thinking. I'm still trying to find a spot that feels good to me.


Yes, the idea to try it out came from Handmade Hero for sure, plus we embraced a similar method at work. Smiley I agree with the "healthy balance" though, it's no use going to extremes in either direction. I was mostly just surprised how easy it was doing things the "hard way" and how much more clean everything feels. As with all coding though, the best tool for the job often varies a lot and the best you can do is to gain experience with different tools to make it easier to decide what to use on a case-by-case basis!
Logged

JWki
Level 4
****


View Profile
« Reply #4550 on: February 20, 2017, 05:52:40 AM »


Also, nice work on the serialization, though I never really liked having to wrap fields, I find it a bit too intrusive, but as long as it works for you that's great!
Yeah, it feels slightly dirty, but it's only for the fields that I want to expose in the editor anyway and not all of them, and I ended up just overloading arrow and dereference operators to make the wrapper work essentially like a pointer, so the syntax isn't unfamiliar, and as far as I've understood, the macro expansion that compiles into the final build will be absolutely zero-cost.


An alternative approach would be to have a tool that runs over your code, looks for annotation macros or something similiar and generates either external metadata that the editor understands or code that you in turn include that contains autogenerated factory functions and the like.
Logged
qMopey
Level 6
*


View Profile WWW
« Reply #4551 on: February 20, 2017, 08:56:08 AM »

Quite ecstatic! Last night implemented DEFLATE compressor. I was tracking down a bug for 8 hours straight on Sunday, eventually found it after a debugging tip from Charles Bloom. Turns out he's a really nice guy and promptly answered my email Well, hello there! !

Out of all the problems I have ever tried to solve hands down writing a good compressor was the hardest. I doubt I will ever again write another one on my own time. The compressor was for a single-file header lib I've been making that can do PNG load/save along with a single function to construct a texture atlas. PNG uses DEFLATE on each row of pixels. So far it's about 80-90% as effective as whatever is inside of 7-zip for zip files (almost certainly some kind of DEFLATE implementation), so my game no longer needs zlib, libpng or any other giant old libraries written in 1980's-1990's.

Also plan to hook it up to large packets that get sent over netcode and compress them before sending over the wire. Stuff like when two players initially connect and need to sync a bunch of states.
Logged
JWki
Level 4
****


View Profile
« Reply #4552 on: February 21, 2017, 03:29:24 AM »

Messed with RawInput on windows for the first time last night, with the help of this useful blog post:
https://blog.molecular-matters.com/2011/09/05/properly-handling-keyboard-input/

Got it to recognize all the keys on the keyboard I think, including the weird ones. I'm actually not sure I'll even need this because the project that's been starting to grow in my head recently is probably better suited for gamepad input, but it's still nice to play around with new things. Also maybe I'll do a 180 and make a mech simulation instead. It has happened before.
Logged
Schrompf
Level 9
****

C++ professional, game dev sparetime


View Profile WWW
« Reply #4553 on: February 21, 2017, 03:39:46 AM »

https://github.com/Schrompf/sniis - Uses RawInput to much success on Windows, and offers Controllers, too. Just in case you want a readymade lib. It's fun to fiddle with the technical details, so feel free to use whatever you want.
Logged

Snake World, multiplayer worm eats stuff and grows DevLog
JWki
Level 4
****


View Profile
« Reply #4554 on: February 21, 2017, 04:24:41 AM »

https://github.com/Schrompf/sniis - Uses RawInput to much success on Windows, and offers Controllers, too. Just in case you want a readymade lib. It's fun to fiddle with the technical details, so feel free to use whatever you want.

Looks nice, I'll be sure to look into it when I mess with input somewhat more, pretty sure there's some things in there I could make use of.
Logged
oahda
Level 10
*****



View Profile
« Reply #4555 on: February 22, 2017, 03:07:25 AM »

An alternative approach would be to have a tool that runs over your code, looks for annotation macros or something similiar and generates either external metadata that the editor understands or code that you in turn include that contains autogenerated factory functions and the like.
Yep, we'll have to see if I end up using this in any shape at all, but it's always fun to experiment and learn new stuff!

The compressor was for a single-file header lib I've been making that can do PNG load/save
Sharing is caring. C;
Logged

qMopey
Level 6
*


View Profile WWW
« Reply #4556 on: February 22, 2017, 09:16:22 AM »

The compressor was for a single-file header lib I've been making that can do PNG load/save
Sharing is caring. C;

Oh I've link it around these forums a few times: tinydeflate
Logged
JWki
Level 4
****


View Profile
« Reply #4557 on: February 26, 2017, 01:57:43 AM »

Had a nice idea on how to make my platform API nicer while also getting rid of all global state in the platform layer's implementation and now loading libraries looks somewhat like this

Code:
GN_MODULE_EXPORT void EntryPoint(PlatformAPI* platformAPI)
{
printf("Hello Runtime\n");

GN::PlatformInterface platform;
if (!platform.CreateAPIHooks(platformAPI)) {
printf("failed to create platform API hooks\n");
return;
}

using EntryPoint_Func = void (*) (void);

DynamicLibraryHandle vulkanLib = platform.LoadDynamicLibrary("vulkan");
auto VkEntryPoint = platform.LoadFunction<EntryPoint_Func>(vulkanLib, "EntryPoint");

VkEntryPoint();

platform.ReleaseDynamicLibrary(vulkanLib);

return;
}

The issue I had before was that I get pretty OCD when it comes to global state, something I usually solve by having context pointers that I pass around. For example, dynamic libraries are kept track of in a DLLStorage struct in my windows implementation of the platform layer to implement caching and the like. Because I don't use a virtual interface to pass the platform API to the consumer of that API, the DLL storage used to be global within the windows layer so that the implementations of the API calls could access it.
So I introduced a context pointer to the PlatformAPI struct, leading to all the API calls now taking that pointer as first argument. The PlatformInterface simply wraps that up because the calls get quite long and ugly:

Code:
GN_FORCEINLINE
DynamicLibraryHandle LoadDynamicLibrary(const char* name)
{
    return m_platformAPI->dynamicLib.LoadDynamicLib(m_platformAPI->platform, name);
}

This combines the advantages of the approach I took so far with a somewhat nicer, consistent interface.
It introduces a choke point because as the platform API is extended, I have to extend the PlatformInterface, but I can live with that.
Logged
oahda
Level 10
*****



View Profile
« Reply #4558 on: February 26, 2017, 11:26:50 AM »

What's that force inline macro? o:
Logged

JWki
Level 4
****


View Profile
« Reply #4559 on: February 26, 2017, 02:46:00 PM »

It resolves to the compiler specific keyword to force a function to be inlined.
__forceinline on MSVC, it isn't defined for clang and linux yet but there exist equivalent keywords.
Logged
Pages: 1 ... 226 227 [228] 229 230 ... 279
Print
Jump to:  

Theme orange-lt created by panic