Jump to content

  • Log In with Google      Sign In   
  • Create Account

Banner advertising on our site currently available from just $5!

1. Learn about the promo. 2. Sign up for GDNet+. 3. Set up your advert!

Pink Horror

Member Since 02 Jul 2013
Online Last Active Today, 07:38 PM

#5236377 what really get and set do?

Posted by Pink Horror on 23 June 2015 - 11:01 AM

the basic type foo {get;set;} is mostly not that great, unless you want to refactor later and change have the property do something else (like raise an event when changed or something). But the syntax does let you do things like type foo {get; private set;}, which I like as a fairly nice way of having a public facing readonly property without a second member variable declaration.


Yes, I was commenting on the typical usage of just putting "{get; set;}" on the end of variables. There are some more useful things you can do with the syntax - access restriction and overriding inherited properties are both possible. But doing it just to refactor later makes little sense to me, unless you are really concerned that your variable will be used in reference parameters everywhere. You can refactor from a variable as well. You don't have to start with a property to be allowed to refactor something.

#5236365 what really get and set do?

Posted by Pink Horror on 23 June 2015 - 10:16 AM

By making x into a property, you prevent it from being used as a reference parameter.


I personally don't see much of the point in auto-implemented properties in C#. When I first saw C# had properties, I thought the whole point was to make something that had the same syntax as a public member variable, so for refactoring purposes you could easily switch between the two choices. In my opinion, that should have made public member variables more acceptable. I guess that didn't happen, which could be why this was added into C# in version 3.0.

#5236191 std::unordered_map random insertion infinity loop

Posted by Pink Horror on 22 June 2015 - 12:18 PM

how would I have fixed this issue, without switching to DLLs, or did this only applied to the "warnings" part of your statement?


Well, once you go down the DLL route, your choices get limited. With any core library that you create yourself, you face a choice similar to the Visual Studio project choice to have the DLL or non-DLL version of the Runtime library. You can either design your library so that whatever static data it has can have multiple instances (best case is not having any), or you can limit how you use your library to prevent issues (such as making sure all memory allocated in one DLL gets freed in the same DLL). Really, though, if you have otherwise decided on DLLs, putting the engine in one could be the best solution. I suppose another option would be building the engine into the exe, putting an interface on your engine, and passing that into all your DLLs somehow.


With no DLLs, now there should only one executable instance of every library you wrote, so these problems do not come up. The warning issue I've seen here is that, if for example you had a central math library, you might think it's natural to link that library into every other library that uses math. Instead, you should link it only into the actual executable. That way each library isn't trying to link in its own copy of the math library. It's a pretty simple problem to avoid but I've seen professional software that has it.


So, yes, I was just referring to the warnings. You have to consider many more issues once you start making DLLs.

#5236157 std::unordered_map random insertion infinity loop

Posted by Pink Horror on 22 June 2015 - 08:06 AM

I find it hard to believe there is any template problem that can actually be FIXED by moving to a DLL (especially since templates are a compile-time thing and being in a DLL doesn't matter assuming everything is instantiated and exported properly). But hey, there's always a first time


My guess is that he had a bunch of warnings or worse by statically linking the same libraries into multiple other libraries and then linking them all together, resulting in multiple copies of everything linked together. Switching to DLLs avoids that problem - but of course actually fixing the static linking problem would have also worked.


Edit to avoid multiple posts:

But more on the topic of private members (not?) having to be exported, I'm still confused since all of you guys are suggestion that even private members MUST be exported, while I only find information saying it doesn't have to be done otherwise:


If every constructor that gets used is exported, those should be used. If you can keep anything including the header for that class from generating any code related to the class, everything should be all right. We don't have any proof you are doing that.


This particular example you posted doesn't have a constructor, so it'll use the default constructor, which will be created in every module that uses the class. That's a problem. However, I doubt that's your entire class definition, so I don't think it is a real problem. You could make a PIMPL style class to get around this if you want to try that out.


In the emplace-line, I call sys::toPointer, which assigns the raw pointer to a sys::Pointer. I would normally call sys::makePointer which would create the object directly in sys::Pointer, but in this case I would have to do another unnecessary map lookup.


sys::Pointer<Handler> InputHandlerAssetLoader::OnLoad(std::string stData)


You said that sys::Pointer is a std::unique_ptr. (Is it a typedef?) Here's what I think this function does: First this function creates a new object. It then adds a unique_ptr to that object to an internal map. It then returns a unique_ptr to the same object. That's bad. Am I wrong? Once again, though, this isn't all of your code, so I am not sure I am picking on a real problem. However, I don't know what else you expect people to do with this much code.

#5235799 std::unordered_map random insertion infinity loop

Posted by Pink Horror on 19 June 2015 - 07:47 PM

Now, I hope I have given you a good overview of whats going on. As you can see, I'm pretty much lost on being able to debug anything since the code lies way out of my control and there is no real pattern that I could inspect (I'm not going to debug through 100 callstack entries of STL code, ugh). Now I want to ask you, if you have any idea on what could be going on, especially since this bug is so damn sporadic, but always happens in the same place. ANY input would be highly appreciated, from experience based to blindly quessing in the air. Thanks in advance...


My blind guess is that I wonder what happens when you change stName to a value parameter instead of a reference. Whatever multi-thread issue you have, if you have one, might be messing with your asset names.


I also wonder what happens if you try to reproduce the problem in a single source file instead of using DLLs. It's really easy to get really strange bugs when you are living dangerously with DLL boundaries.


I am also curious about the rest of the code in the OnLoad function. You return a raw pointer from AddHandler. You say that sys::Pointer is a unique_ptr. How are you turning that raw pointer into a unique_ptr when your Handler is owned by that unordered_map?

#5235742 Interpreting unordered_map key as blob of bytes for hashing?

Posted by Pink Horror on 19 June 2015 - 01:07 PM

There's no reason to copy at all, really, if the class is POD/standard layout. Just reinterpret_cast(this) and pass that to the hash function.


You mentioned the reason not to do this earlier: the pad bytes will get hashed.

#5235712 Interpreting unordered_map key as blob of bytes for hashing?

Posted by Pink Horror on 19 June 2015 - 10:23 AM

I feel the cleanest way is to dump the bytes of the key (the bytes I want to include) into an array and hash that with std::hash (or some specific hash function). Is that how its usually done?

Currently I use something more 'structure-aware' like hashing each member variable and summing the hashes, or such, but thats no good.


What is the real difference here?


With both solutions, you have to identify "the bytes I want to include", so you're choosing particular member variables to hash either way.


Meanwhile, the first solution involves copying things into an array. The second one doesn't. That's the only actual difference. The choice seems obvious.


If you don't want to come up with your own hash functions, you can use boost. It has boost::hash functions defined for a bunch of primitives and containers. It also has a hash_combine function for putting the individual hashes together. You don't have to think about what's going on internally.

#5235571 open address hash map

Posted by Pink Horror on 18 June 2015 - 04:31 PM

I could be missing it somewhere, but it looks like your erase function is missing the adjustment necessary for an open addressing hash table to continue to find everything after a cluster has formed from hash collisions, and an entry is removed from the middle of the cluster.

#5235317 [Win32] Crash log: StackWalker not showing full callstack

Posted by Pink Horror on 17 June 2015 - 01:22 PM

So pretty much identical to that in the tutorial. Do I have to do something else to get the complete callstack of where an access violation, nullptr-exception etc is caught? Is this even possible using this (or any other) method? I'd really like to have a complete crash log in case one happens, for its otherwise very hard to debug on clients PCs when they don't have a C++ debugger installed... any help or suggestion would be appreciated. Thanks!


As you can see in your call stack, abort directly calls raise which then raises the signal, so your signal handler is called right there. It looks like the signal for illegal access doesn't happen until the exception is caught by something else, and that's the correct stack for when that signal is actually thrown. I'm not sure if it'll be any different, but you could try not using the signal function. SetUnhandledExceptionFilter or AddVectoredExceptionHandler might do something different.

#5234968 Slow down when using OpenMP with stl vector per thread

Posted by Pink Horror on 15 June 2015 - 03:40 PM

I think, if you want to stick to the STL, you should replace the set with a priority queue and see what happens. The default priority queue is backed with a vector so you shouldn't have as many allocations. You won't be able to remove copies of the same node from the queue when you find a better distance, but the algorithm should work regardless.

#5234909 Slow down when using OpenMP with stl vector per thread

Posted by Pink Horror on 15 June 2015 - 10:49 AM

Actually the algorithm computes shortest paths to smooth cluster boundaries from mesh segmentation - no math here, just walking lists and storing data.

The growing vectors are the two shown in the listing, std::list in the new border to store the path, plus a std::set queue in Dijkstra.


Could we see the code that uses this list and this set? I have a feeling they're more responsible for the problem.

#5230920 Too clever...?

Posted by Pink Horror on 25 May 2015 - 04:31 PM

What is best practice?  Is there even such a thing in this regard?  Swift can return tuples.  That is a nifty thing.  Too bad I am reluctant to be tied to a system that is so locked to one platform and one platform only.


You should have an assert statement, unless you actually expect it to be valid to pass in bad bounds to that function during normal operation.

#5230069 Circle embedded in line-- fastest vector to unembed

Posted by Pink Horror on 20 May 2015 - 11:40 AM

I don't know if this is very different from what you have, but it feels more natural to me:

Vector ray_direction = p2 - p1;
Vector normal(-ray_direction.y, ray_direction.x);
Vector from_p1_to_pt = pt - p1;
Vector move_direction = normal * dot_product(normal, from_p1_to_pt);


Does this work? I'm trying to figure out why you would multiply a vector by a dot product, and then immediately normalize it. I don't see how that would change its direction.

#5226979 How to separate xyManager effectively into smaller responsibility classes?

Posted by Pink Horror on 03 May 2015 - 11:12 AM

Well, i am pretty sure passing some refs/pointers all around the code base just because somewhere deeply in the codebase somebody might want to use it is a bigger antipattern than using singletons...
And if 99 command from 100 don't use it, then i feel like it's unnecessary.


And making a global variable so 1 command out of 100 can access it is... better?


I generally agree with the others who don't like global variables. However, this sometimes results in making "Manager" classes, especially when I cannot think of a better name. After all, everything that is not global has to live somewhere else. I don't really feel like having 50 objects sitting at the bottom of my call stack. To organize them into something more manageable, all of these non-global objects have to be packed together into other objects, which may or may not be "managers". I try to avoid the typical ugliness of a manager by keeping all of the real work in the owned classes instead of the top-level class.


So, if a generic Command class needs to be able to mess with anything in the whole world, maybe you have a "World" object that could be passed into it. With just a World object, you might be able to change any gameplay stuff around, but things like the current user input state or a sound player or any rendering commands would be inaccessible. At least you've partially restricted what a Command can do. If the sound player or rendering or user input were just global variables, there's nothing stopping a Command from touching them. At least with parameters, your intent is clear for what a function is supposed to be able to effect.


If some function is supposed to be able to do absolutely anything to the whole game, and every top-level game class is passed into it, at least it's clear that the function can do anything. You might call it an "antipattern", but changing parameters into global variables doesn't solve the problem apparent with the antipattern. It just hides it. Every global variable is already an implied parameter to everything.

#5226086 Random Number Generation

Posted by Pink Horror on 28 April 2015 - 09:54 AM

I guess this is a programming question, but only indirectly (I wasn't sure where to post it).

Anyway, I need random data, and lots of it! I need many megabytes worth of random bits, and it can't be PSEUDO-random, but actually random (at least in the sense that it wasn't created by any mathematically predictable pattern at all)!


Is there any way to prove that even exists?