Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411490 Posts in 69371 Topics- by 58428 Members - Latest Member: shelton786

April 24, 2024, 05:37:48 PM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)The grumpy old programmer room
Pages: 1 ... 268 269 [270] 271 272 ... 295
Print
Author Topic: The grumpy old programmer room  (Read 738666 times)
LittleTwig
Level 0
**


View Profile
« Reply #5380 on: July 03, 2017, 01:40:31 AM »

My second screen just died and I won't be able to buy a new one in the near future.
Programming on a single screen feels so annoying..
Logged
JWki
Level 4
****


View Profile
« Reply #5381 on: July 03, 2017, 02:18:22 AM »

My second screen just died and I won't be able to buy a new one in the near future.
Programming on a single screen feels so annoying..

I feel you, I have to work on a laptop a lot lately and I feel incredibly trapped inside that little screen.
Logged
Ordnas
Level 10
*****



View Profile WWW
« Reply #5382 on: July 03, 2017, 05:19:43 AM »

Depend, conceptually it's simple, it's hard to tell because I break the typical view of the object I want to simulate. Then I haven't fully implemented and only work on simple case, so who know how detail it can be, if you are expecting GTA level of detail I'm not sure.

But the concept is simple, let say you have a simple city generation and we will ignore traversal. Let say that city have only home and workstation. You know that people are at home from 16h to 8h and at work from 8h to 16h, it's divergent, you can't be at home and at work at the same time. So let say you seed home and work with ID, home and workstation with the same ID seed will generate the same npc, and since the npc is only active in that place at the given divergent time, it's like they go from home to work and viceversa, it can only be at one place at a time because they are generate by each place at different time. My attempt is to generalized that idea to every place, even the street tile, simulating the simulation of deplacement.

It reminds me of SimCity 5, where the developers say that every pedestrian has a realistic path: each one has a home, and it goes to work, and has a proper routine.
Logged

Games:

Photon
Level 4
****


View Profile
« Reply #5383 on: August 04, 2017, 06:25:08 AM »

Over a month without anyone being grumpy? WOW. I almost hate to "necro" this...

Well, I'm not actually grumpy so to say, but I still found a rather perplexing bug. My game started crashing on exit for some reason, and I discovered that it ONLY happens when my recording software is capturing it. The shutdown of the game is pretty minimal stuff (at least from the standpoint of my own code,) so I find it pretty interesting that the one is having an adverse effect on the other. Might be something on the OpenFL side.
Logged
ThemsAllTook
Administrator
Level 10
******



View Profile WWW
« Reply #5384 on: August 04, 2017, 07:21:52 AM »

I've experienced that exact thing on Windows. In my case, what I needed to do to fix it was to add an atexit() handler that would explicitly tear down my WGL context. The usual wisdom is not to waste program time freeing any memory or resources when your program terminates since the operating system reclaims them automatically, but apparently this is a case where it's actually needed.
Logged

JWki
Level 4
****


View Profile
« Reply #5385 on: August 06, 2017, 02:28:04 AM »

Just messed with texture data uploading for what felt like HOURS, keeping getting read access violations when copying texture data from host memory to driver staging memory and pulling my hair over my stride values until I realized that I took a pointer to my data pointer instead of the actual fucking pointer as input.

FML.
Logged
Ordnas
Level 10
*****



View Profile WWW
« Reply #5386 on: August 07, 2017, 12:40:36 AM »

The usual wisdom is not to waste program time freeing any memory or resources when your program terminates (...)

It is debated if you need to clean or not. I think that the best practice is to free resources when the program exits, because doing so you are 100% sure that you don't introduce any problem/leak/dangling pointers afterwards.
Logged

Games:

qMopey
Level 6
*


View Profile WWW
« Reply #5387 on: August 07, 2017, 12:00:09 PM »

The usual wisdom is not to waste program time freeing any memory or resources when your program terminates (...)

It is debated if you need to clean or not. I think that the best practice is to free resources when the program exits, because doing so you are 100% sure that you don't introduce any problem/leak/dangling pointers afterwards.

OS makes 100% sure for you.
Logged
JWki
Level 4
****


View Profile
« Reply #5388 on: August 07, 2017, 01:28:12 PM »

The usual wisdom is not to waste program time freeing any memory or resources when your program terminates (...)

It is debated if you need to clean or not. I think that the best practice is to free resources when the program exits, because doing so you are 100% sure that you don't introduce any problem/leak/dangling pointers afterwards.

OS makes 100% sure for you.

Or so it should. In practice I think there's a FEW things that might leak - I'm not sure on driver guarantees in Vulkan/D3D12 for allocated GPU memory but should be covered by the driver, however I hear stories about some win32 handles floating around, not sure what exactly it was tho.

In general I agree tho, the OS should do the cleanup for you and it does in fact for almost everything that ever matters except for aforementioned oddities and those could be considered bugs in the OS. It's a massive waste to walk through a thousand destructors and call free() on a million things when your program shuts down.
Logged
Ordnas
Level 10
*****



View Profile WWW
« Reply #5389 on: August 07, 2017, 11:51:03 PM »

(...) It's a massive waste to walk through a thousand destructors and call free() on a million things when your program shuts down.

Anyway, this question should not ever arised, because by design, every class should delete what they allocate, and it should not have knowledge where or why it is being destructed.

If the program shuts down, and it leaks, probably there are memory leak at run-time.
Logged

Games:

qMopey
Level 6
*


View Profile WWW
« Reply #5390 on: August 08, 2017, 12:46:08 AM »

by design, every class should delete what they allocate, and it should not have knowledge where or why it is being destructed.

Why is that a good thing?

If the program shuts down, and it leaks, probably there are memory leak at run-time.

Why are run-time leaks bad?
Logged
JWki
Level 4
****


View Profile
« Reply #5391 on: August 08, 2017, 05:41:03 AM »

(...) It's a massive waste to walk through a thousand destructors and call free() on a million things when your program shuts down.

Anyway, this question should not ever arised, because by design, every class should delete what they allocate, and it should not have knowledge where or why it is being destructed.

If the program shuts down, and it leaks, probably there are memory leak at run-time.

Going to wait for you to reply to qmopey before I go into why I disagree with that.
Logged
Ordnas
Level 10
*****



View Profile WWW
« Reply #5392 on: August 08, 2017, 11:56:29 PM »

Why is that a good thing?

Why are run-time leaks bad?

Delete what you allocate, or you end you free memory; then it is a good thing to avoid coupling that will introduce errors.
Logged

Games:

JWki
Level 4
****


View Profile
« Reply #5393 on: August 09, 2017, 12:35:24 AM »

Why is that a good thing?

Why are run-time leaks bad?

Delete what you allocate, or you end you free memory; then it is a good thing to avoid coupling that will introduce errors.


Okay so I'll understand this as "leaking memory is bad because you'll run out of it" and while technically true, there's leaks and then there's real leaks - it's one thing if you allocate like crazy, especially small allocations, and fragment your heap in a way that ends up killing your performance (running out of memory is a concern on platforms without virtual memory too) - but the advice should be to just not allocate so many individual things and instead allocate one big block and then use a fitting allocator for that system.
About avoiding coupling, actually coupling is increased when your classes all manage their resources themselves because now when you want a higher level mechanism that resource management goes through - for debugging, or to abstract asset loading from packages or whatever - suddenly all those things that manage their own resources have to be rewritten! And because you don't want to change the interface, you make your higher level system a singleton or a global and the coupling is increased exponentially.
I've found that almost always you want inversion of control - something that works with resources shouldn't have to deal with how those resources are obtained and be handed them by a higher level system.

For example, what I very often see is something like a texture class that has a FromFile() method or whatever that takes a path and will initialize the texture with the texture data from that file - and everytime I see it I wonder who thought this was a good idea. Why would a texture care how to load an image file? What about different file formats? What if all your textures have to be loaded from a central texture package? How is this decoupled in any way?
Logged
Ordnas
Level 10
*****



View Profile WWW
« Reply #5394 on: August 10, 2017, 12:12:46 AM »

(...) the advice should be to just not allocate so many individual things and instead allocate one big block and then use a fitting allocator for that system.

If with fitting allocator you are meaning a stack allocator, that would be perfect to avoid fragmentation only in games where your game is linear (loading screen -> play level 1 -> loading screen ->play level 2) and each level fits into memory entirely.

In games where need to support streaming (like open-world games) other resource allocation technique need to be used, like the pool allocator and the chunk allocator (basically linked-lists of chunk memory, the latter optimized to avoid wasted memory). In these types of games, you need to be carefully of what you are deleting and when.

About avoiding coupling, actually coupling is increased when your classes all manage their resources themselves because now when you want a higher level mechanism that resource management goes through (...)

Rendering, physics, input, all this subsystem interacts themselfs, so there is coupling, but only between the main subsystems of the engine foundation (the graphics system, the memory managment, audio engine ...), to minimize coupling between classes from different subsystems (a texture and a physics property).  

The coupling increased exponentially is not a problem if you are building the subsystems correctly (a global queue of managers, where you are defining what needs to be initialized first, and when the programs shuts down the order of initialization is reversed).

Today this is not a problem anymore because there are many references of how to do it properly, and a singleton class that works as a manager, added in a priority queue, is always the right way to do it.
Logged

Games:

JWki
Level 4
****


View Profile
« Reply #5395 on: August 10, 2017, 12:58:37 AM »

(...) the advice should be to just not allocate so many individual things and instead allocate one big block and then use a fitting allocator for that system.

If with fitting allocator you are meaning a stack allocator, that would be perfect to avoid fragmentation only in games where your game is linear (loading screen -> play level 1 -> loading screen ->play level 2) and each level fits into memory entirely.

In games where need to support streaming (like open-world games) other resource allocation technique need to be used, like the pool allocator and the chunk allocator (basically linked-lists of chunk memory, the latter optimized to avoid wasted memory). In these types of games, you need to be carefully of what you are deleting and when.

About avoiding coupling, actually coupling is increased when your classes all manage their resources themselves because now when you want a higher level mechanism that resource management goes through (...)

Rendering, physics, input, all this subsystem interacts themselfs, so there is coupling, but only between the main subsystems of the engine foundation (the graphics system, the memory managment, audio engine ...), to minimize coupling between classes from different subsystems (a texture and a physics property).  

The coupling increased exponentially is not a problem if you are building the subsystems correctly (a global queue of managers, where you are defining what needs to be initialized first, and when the programs shuts down the order of initialization is reversed).

Today this is not a problem anymore because there are many references of how to do it properly, and a singleton class that works as a manager, added in a priority queue, is always the right way to do it.


I agree with the point on allocators. It's exactly what I meant, I wasn't talking about any kind of allocator specifically. By fitting allocator I meant the allocator that fits the job.

I heavily disagree with everything else in there but I don't want a derailing discussion so I'll just say that in my experience you want your systems to be LESS coupled the deeper down in the stack you go and connect them with HIGHER level systems, and I found that to be perfectly working without any need for singletons. Actually better than back when I was using singletons.
Logged
Crimsontide
Level 5
*****


View Profile
« Reply #5396 on: August 13, 2017, 03:08:59 AM »

I heavily disagree with everything else in there but I don't want a derailing discussion so I'll just say that in my experience you want your systems to be LESS coupled the deeper down in the stack you go and connect them with HIGHER level systems, and I found that to be perfectly working without any need for singletons. Actually better than back when I was using singletons.

I'm going to agree with JWki here.  I've found that as you go deeper, you want less coupling.  Its a little strange at first, but it makes code reuse more than just a pipe-dream.

For example, my VulkanLib wrapper/engine I'm working on has almost no external dependencies, and none that are tied to any particular OS, platform, system, or game engine.  Its mainly just C++ code interfacing with Vulkan.  In a Windows library (which handles all the Windows OS stuff) I provide the OS specific tie-ins to VulkanLib (dll loading, surface creation, etc...).  There's no Windows specific stuff in VulkanLib, rather there's Vulkan specific stuff is in WindowsLib.  That way if I were to port to Linux or Android, the entire Vulkan 'back-end' wouldn't need anything changed.

As far as the delete on exit, I agree with Ordnas here.  Your classes shouldn't worry about the context they are used in.  They should generally be context agnostic to allow as much re-use as possible.  If at the end of the program you want to use std::terminate() or something similar to avoid unwinding the stack, then by all means; but destructors should always free any data they allocate.  RIAA is fundamental to good C++ programming.
Logged
Ordnas
Level 10
*****



View Profile WWW
« Reply #5397 on: August 13, 2017, 10:29:32 AM »

(...) you want your systems to be LESS coupled the deeper down in the stack you go and connect them with HIGHER level systems, and I found that to be perfectly working without any need for singletons. (...)

For example, my VulkanLib wrapper/engine I'm working on has almost no external dependencies, and none that are tied to any particular OS, platform, system, or game engine.  Its mainly just C++ code interfacing with Vulkan.  In a Windows library (which handles all the Windows OS stuff) I provide the OS specific tie-ins to VulkanLib (dll loading, surface creation, etc...).  There's no Windows specific stuff in VulkanLib, rather there's Vulkan specific stuff is in WindowsLib.  That way if I were to port to Linux or Android, the entire Vulkan 'back-end' wouldn't need anything changed.

The perfect program wants that every system is independent from each other. Unfortunately this is not possible in real software. Game engines need low-level sub-systems that manages tasks like file system, memory usage, and asset managment as audio, textures and animations. Because these systems interact with each other, it will be an inevitable interdependency between them. You simply can't ignore the FileSystemManager from the TextureManager if you want your texture being loaded, and a PhysicsManager probably needs to interface with the AnimationManager is you want your ragdoll working on your skeletal mesh.

Then your game engine initialization will be something like this:

Code:
int main(int argc, const char* argv)
{
    gMemoryManager.init();
    gFileSystemManager.init();
    gVideoManager.init();
    gTextureManager.init();
    g.RenderManager.init();
    g.AnimationManager.init();
    g.PhysicsManager.init();
    // ...

and an order of initialization needs to be correctly defined, or your RenderManager cannot find the graphics interface.

If by design you decide that each sub-system is global, then these systems are static, because having two VideoManager has no meaning and is dangerous. So a common design pattern is useful here, and a Singleton prevents to having more of one instances of that class. Singletons are a common way to implement managers.

I agree that you will need to avoid coupling as much as possible, but you can't avoid it completely. You will minimize the coupling to a minimum using a "Facade Pattern", a class that provides a single interface to a large collection of related classes, so in case of an heavily modified subsystem you will not have compile-errors from over the place: https://en.wikipedia.org/wiki/Facade_pattern
Logged

Games:

Crimsontide
Level 5
*****


View Profile
« Reply #5398 on: August 13, 2017, 05:30:08 PM »

Of course there will always be coupling, the question is where does the coupling happen.  Normally it happens at the 'top'/'deep' (called high level in most books) part of your dependency chain, with inversion it happens at the 'bottom'/'shallow' (called low level) end of the chain.  Dependency inversion often fixes the singleton spam problem.

For example, imagine you have some sort of file manager.  Normal dependency gives you something like:

OS specific file routines <- file manager <- game engine <- main game loop <- OS specific entry/initialization

likewise for a graphics manager:

OS specific windowing routines <- graphics API(s) <- graphics engine <- game engine <- main game loop <- OS specific entry/initialization

You'll find that quite often with normal dependency chains the OS/platform specific stuff will start to pop up in all your systems (as well as other high level interdependencies).  Now if its something that is always there (like the standard library) its a non-issue.  But as soon as its not a guarantee, you have tons of branches, checks, or worse #define's littering your code.

With dependency inversion you end up with something like:
file manager <- game engine <- main game loop <- OS specific entry/file wrapper
graphics API(s) <- graphics engine <- game engine <- main game loop <- OS specific entry/initialization/window wrapper

The key difference is that your OS/platform specific code is in one place, not scattered through out.  Your interface to the OS is then implemented through fixed/known interfaces.  Moving to new platform, adding a system, or porting a system to a whole new program/game now become rather trivial tasks.

https://en.wikipedia.org/wiki/Dependency_inversion_principle
Logged
Photon
Level 4
****


View Profile
« Reply #5399 on: August 14, 2017, 07:30:30 AM »

Oh goodness, what did I start?

Who, Me?
Logged
Pages: 1 ... 268 269 [270] 271 272 ... 295
Print
Jump to:  

Theme orange-lt created by panic