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!


l0calh05t

Member Since 16 Dec 2000
Offline Last Active Today, 06:52 AM

#5210798 OpenGL framebuffer management

Posted by l0calh05t on 15 February 2015 - 05:15 AM


If you read *pointer++, then it reads as "dereference this pointer and increment it". People read from left to right1, and so what you read is just what happens, albeit somewhat contorted (the increment actually happens first because of precedence, but the old value is retained for the dereference).

 

And as I just had to fix a related bug on friday... "dereference this pointer and increment it" is not correct, as a copy is dereferenced. When does this become relevant? Whenever you have to deal with InputIterators. Because incrementing an InputIterator may invalidate any other copies of the iterator. Including those returned by postfix operator ++. So a=*it++; will not behave the same as a=*it; ++it;

 

The morale of the story? Don't use postfix ++




#5209546 OpenGL framebuffer management

Posted by l0calh05t on 09 February 2015 - 02:38 AM


If you read *pointer++, then it reads as "dereference this pointer and increment it". People read from left to right1, and so what you read is just what happens, albeit somewhat contorted (the increment actually happens first because of precedence, but the old value is retained for the dereference).

 

I could just as well read it as "dereference pointer and increment the result" (which this doesn't do)

 


If you read *++pointer then this also reads as "dereference this pointer and increment it", but that isn't what is happening thanks to right-associativity. So you end up dereferencing a different object than you might naively think you are.

 

And in this case "dereference the incremented pointer" (which it does do)

 

The whole "reading direction" argument is nonsense as it matters a lot what words you place in between.




#5204883 Returning a nullptr refence, how bad is my teammate?

Posted by l0calh05t on 17 January 2015 - 02:56 AM

Yes, in this case it would cause a copy. As servant of the lord suggested, a reference to a static or global object could be returned (and as the reference is const, the usual issues with static or global variables don't apply.

 

But the code isn't written in an efficient manner anyways, as first find is called to check if the object exists... and then the [] operator does an internal find again. If you are already have an iterator use it!

static const std::string empty;
const std::string& SoundHandler::getPlayingFromPlaylist(const std::string& playlistName)
{
    //Check to see if the playlist exists
    auto iter = playlists.find(playlistName);
    if(iter == playlists.end())
        return empty;

    return iter->currentlyPlaying;
}



#5204719 Returning a nullptr refence, how bad is my teammate?

Posted by l0calh05t on 16 January 2015 - 09:22 AM


EDIT:: The compiler gave a warning, he though its okay.

 

That is why I love -werror or /WX. Reduces the chances of idiot programmers to ignore the warnings.




#5201789 OpenGL framebuffer management

Posted by l0calh05t on 04 January 2015 - 01:07 PM

obviously you should have written

for (auto it = framebuffers.Begin(); it != framebuffers.End();)
{
    if (it->second->framesSinceUse > MAX_FRAMEBUFFER_AGE)
        it = framebuffers.Erase(it);
    else
        ++(it++)->second->framesSinceUse;
}



#5196968 Which of these games would you like to read more about?

Posted by l0calh05t on 08 December 2014 - 09:30 AM

I went for System Shock II because the FPS/RPG type of game has become far more widespread since then (an pointing out the evolutionary changes could be interesting)

Aside from Raptor (seems too simple) and Scorched Earth (seems too unusual, other turn-based game options could be interesting), I think all of them would be interesting.




#5194559 Switching from CreateThread() to Thread

Posted by l0calh05t on 25 November 2014 - 03:02 AM

I had a closer look at your code, and although it does have threading issues as others have stated, I suspect your problem has a different cause and that is the following line:

using namespace std;

Why is this an issue? Both WinSock and C++11 (more specifically the <functional> header which in your case is included by <thread>) define a bind function.

Either don't use using namespace at a global scope (preferred), or be specific and use the global version of bind that WinSock defines by using ::bind.

 

See http://stackoverflow.com/questions/20314343/c-including-thread-redefines-winsock-function-bind




#5187621 What a web I Weave !

Posted by l0calh05t on 17 October 2014 - 04:11 AM

Spaces for indentation are utter bullshit. Tabs are smaller, more flexible (can be adjusted as preferred) and have no disadvantages, except in crappy forum software that doesn't properly support tabs. Using tabs for alignment beyond the first non-whitespace character will break things though. Though aligning variables and other OCD bullshit is a waste of time anyway.

 

Tabs for indentation.

Single spaces for separation.

Anything else is just plain dumb.




#5184335 Funniest line of code ever ?

Posted by l0calh05t on 01 October 2014 - 08:30 AM

 

Personal favorite of mine (from the first version of my 2D engine back in 2009) 

	runRight = new ANIM();
	runLeft = new ANIM();
	runFront = new ANIM();
	runBack = new ANIM();
	idleRight = new ANIM();
	idleLeft = new ANIM();
	idleBack = new ANIM();//those of you with OCD will HATE me for these lines...
	idleFront = new ANIM();//if you don't have OCD, you have no idea what I'm talking about.

Meh, I find the inane repetition far more annoying

for(auto anim : {
		&runRight, &runLeft, &runFront, &runBack,
		&idleRight, &idleLeft, &idleFront, &idleBack
	}
)
	*anim = new ANIM();



#5173962 CMake (some random questions)

Posted by l0calh05t on 15 August 2014 - 01:14 PM

  1. Does another_library use library? You should consider using target_include_directories instead of include_directories
  2. I typically use a CMakeLists.txt for each target. This is advantageous should you at some point decide to make the projects individually buildable (I usually have a cmake_minimum_required() and project() in every target-CMakeLists)
  3. As Mnemotic said. OSX uses so called App Bundles afaik, which is similar to the windows solution, but packaged in a zip.



#5158078 Metal API .... whait what

Posted by l0calh05t on 04 June 2014 - 06:17 AM

 

Metal's C++ based shader language is an interesting idea. Generics/templates might be fun.

I don't think the shader langauge is c++ based. I never seen a double square bracket in c++. Looks more like object c to me

 

Like these? http://en.wikipedia.org/wiki/C++11#Attributes




#5138675 Ugh! Your shorthand is too short!

Posted by l0calh05t on 13 March 2014 - 06:23 AM


For instance, an electronic engineer will know that the formula for calculating a charging voltage of a capacitor in an RC circuit is:

U = U0 * (1-e^(-t/(R*C)))



So in code, I will reflect exactly that:

double U = U0 * 1-pow(e, 0.0-t/(R*C));

Every non-electronic engineer is going to look at that and go "WTF IS THIS CRAP".

 

The electrical engineer might wonder though why you wrote 0.0-t/(R*C) instead of just -t/(R*C) (is -0.0 an issue for the pow function you are using?). And the computer scientist might wonder why you are using pow(e,x) instead of exp(x) which is usually faster. And both might notice you forgot an opening parenthesis wink.png In any case it wouldn't hurt anyone to write

 

double voltage = starting_voltage * (1. - exp(-time/(resistance * capacitance)));

 

Instead, as then both the electrical engineer and the computer scientist would probably have a rough idea what its about, at the cost of only a few keystrokes (which tend to be fairly cheap wink.png).




#5138671 Industrial Strength Hash Table

Posted by l0calh05t on 13 March 2014 - 06:11 AM


Using braces instead of brackets for trying to call the constructor of an object

 

That's actually valid in C++11 and called uniform initialization syntax.




#5136040 Using a vector of base classes with CRTP

Posted by l0calh05t on 03 March 2014 - 03:35 AM

template<typename T>
std::vector<T> collection;
^^^ You can't have a templated variable like that.
That's saying, that when someone tries to use 'collection', instantiate a version of it for each T that they use... You use templates like that on functions/classes, but not variables.
e.g.

C++14 will add template variables (see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3651.pdf)




#5127466 Poker monster

Posted by l0calh05t on 30 January 2014 - 09:06 AM

Yuck. So many named non-iterble things. So much code repetition. Heres an almost 20x shorter Python solution:

from collections import Counter

with open('poker.txt', 'r') as f:
	hands = [hand.strip() for hand in f]
	
values = [chr(ord('2')+k) for k in range(8)] + ['T', 'J', 'Q', 'K', 'A']
ace = values.index('A')
hands = [hand.split(' ') for hand in hands]

hand_values = [[values.index(card[0]) for card in hand] for hand in hands]
hand_suits = [[card[1] for card in hand] for hand in hands]

hand_values = [(hand[:5], hand[5:]) for hand in hand_values]
hand_suits = [(hand[:5], hand[5:]) for hand in hand_suits]

wins = [0, 0]
ties = 0
for vs, ss in zip(hand_values, hand_suits):
	rankings = []
	for v, s in zip(vs, ss):
		v = sorted(v, key=lambda x: [Counter(v)[x],x]) # bugfix
		straight = all(a + 1 == b for a, b in zip(v, v[1:]))
		flush = s.count(s[0]) == len(s)
		counts = Counter(Counter(v).values())
		if straight and flush and v[-1] == ace: rank = 9 # royal flush
		elif straight and flush: rank = 8 # straight flush
		elif counts[4] == 1: rank = 7 # four of a kind
		elif counts[3] == 1 and counts[2] == 1: rank = 6 # full house
		elif flush: rank = 5 # flush
		elif straight: rank = 4 # straight
		elif counts[3] == 1: rank = 3 # three of a kind
		elif counts[2] == 2: rank = 2 # two pairs
		elif counts[2] == 1: rank = 1 # one pair
		else: rank = 0 # high card
		rankings.append((rank, v[::-1]))
	winning_hand = max(rankings)
	if rankings.count(winning_hand) == 1:
		wins[rankings.index(winning_hand)] += 1
	else:
		ties += 1

print wins
print ties

EDIT: added one line of bugfixing (for card multiples, the multiple cards weren't properly used for decision before the high cards)...






PARTNERS