Jump to content

  • Log In with Google      Sign In   
  • Create Account

Awesome job so far everyone! Please give us your feedback on how our article efforts are going. We still need more finished articles for our May contest theme: Remake the Classics

dilyan_rusev

Member Since 24 Nov 2006
Offline Last Active Today, 06:06 AM
-----

Posts I've Made

In Topic: "this" keyword question

15 April 2013 - 10:40 AM

In my previous work place we were required to use "this" (it was part of the naming convention). At my current job, it is the opposite - it is a bit closer to the Java convention (used only in constructors IF there is a naming conflict... which isn't a poor programming practice for constructors).

I've been doing it both ways for years, and I tend to disagree with 0r0d. It does not decorate *only* fields, but methods as well. Before I started using this (which is slow because of the '.', but a lot faster than c++'s '->' which involves Shift as well), I thought it was slow, inefficient and that it littered the code. And then I changed my mind :) The reasons for this are:

  • In a huge code base, it is really important what comes from where
  • Coloring is cool, but is slow as hell, often buggy, even on powerful, high-end machines
  • Most of the time, I read code. When you deal with a huge code base, with tons of stuff you haven't written, you want to be able to easily analyze the API.
    • First, this immediately tells you the scope of variables and methods.
    • Second, this tells you immediately what is static, and what is instance-bound.
    • For that matter, part of the naming convention was to prefix static methods with their class names even inside the class itself. To your eyes it might seem as an abomination, but it is quite helpful when you swim in unfamiliar code.

Overall, the benefits are that you get a lot of information about the code with just a glance.

The downside (especially with prefixing static methods) is that you often get well beyond the 80 characters per line limit. And nothing kills readability more than horizontal scrolling. This is why we had unofficial coding conventions about how to split the code on multiple lines, so that it remains readable.

 

@SeraphLance - For the sake of readability and API extendability, don't use method extensions or method chaining. For that matter, fluent API != method chaining. Here are some reasons why I've come to dislike both after years of using them (and designing APIs with them)

  • When you see timeInSeconds.Normalize(), you've got no clue what is going on. Is this a method? Is this an extension method? Which class provides this extension? Nothing stops Joe to add the next extension method in another class. The IDE can help you, but you don't have this information at first glance, so it slows down readability
  • Extension methods depend on the namespace. So you have two problems:
    • Namespace pollution - when you put too many extension methods in some global namespace (God forbid you put anything in System!)
    • Discoverability - it is very difficult for end users to use your API. What happens usually is that they find out some of your methods "don't work" when they haven't included the right namespace, or they don't ever discover them.
  • Extension methods are static,
    • ... and they inherit all the Builder pattern problems with extensibility. Normal methods can be made virtual and extended by the end user. Static methods are defined in a completely independent class (hopefully one), so they can't be overridden. What's more, they can only access the public members of the class they extend, so extension methods might have bad performance or may not even be able to implement the required functionality without an interface change.
    • You might want to add a method with the same name in the next version of your API... what happens then? Obviously you can't for readability's sake, but then you have to come up with some unintuitive name.
  • Method chaining is bad for debugging. What most users of the API tend to is is stack method calls on a single line. When you don't chain methods, stepping into the correct method is a piece of cake, because, of course, you will invoke no more than one method per line, right?
  • Method chaining is bad for readability. I cringe when I see how most people write their Linq queries... it is a very bad idea to have no coding style about vertical space, yet most work places don't have one. So you have lots of different coding styles when invoking the method chain.
  • Fluent APIs are extremely difficult to come up with. For every non-trivial fluent API, you've got different faces for the concepts you're abstracting. If you put in inheritance, you usually end up all your faces as generic classes with a lot of generic parameters, like Base<TImplementation, TWhatIActaullyNeed> (this happens because you want auto-completion to work when the user chains the super class methods of a derived class). It is way more complicated than composition and/or decorator pattern (which is difficult in terms of discoverability in itself.
 

In Topic: xna dead. now what?

08 April 2013 - 07:10 AM

We use XNA for our game, and it works quite well on all supported platforms. We've got problems with other things, not XNA. We aren't going to switch to anything else in the foreseeable future... there's just way too much code to port, and so long as our clients are happy, we don't care if there aren't gonna be updates for the XNA runtime. Which is even better, cause we'll then have to figure out an update strategy for clients with poor internet access.

Anyway - go and use XNA. When Monogame is ready (and by ready I mean they've got fully functional content pipeline), it might be sensible to do the switch. If you're just starting out - it doesn't really matter. Also, please do consider engines and not frameworks.

 

EDIT:

Don't do C++ if you are a lone dev, apart from purely academic interest. In C++, you've got nothing (in terms of standard libraries). Take for example validation/activation logic. You have to look for REST/JSON/HTTP client/encryption libraries. True, you can code all the shit in sockets, but you'll waste weeks doing meaningless boilerplate instead of getting ahead of your competition. And don't forget the debugging bliss of stepping through assembly for every serious problem that you've got istead of the friendly .NET stack trace. C++ is an option only if you've got the experience AND existing code base you can take advantage of. Plus, you need bigger teams with C++ (which are more expensive in case you're hiring).


In Topic: Eclipse parser/autocomplete not recognizing opengl functions? Any alternative...

29 March 2013 - 07:35 AM

Well, I will try to research this when I'm at home. No Linux or Eclipse at work :)

BTW, function pointers aren't the problem, the parser chokes at two or three-level abstraction introduced by macros. That means it stops resolving after it finds the first macro, i.e it treats glGetBuffer as GLEW_GET_FUN(__glewBindBuffer), which it doesn't parse recursively in order to get to typedef void (GLAPIENTRY * PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer). Also, I'm not sure if the parser would be able to handle the typedef, either :P

This is a complex problem (building AST is one of the shittiest things I've had to do), and many programmers lack the motivation and skill to do this. Plus, most of the time you want to use the information provided by the parser, the code is in broken state (open brackets, missing semicolon, etc), which even further complicates the problem. This is why I trust in commercial IDEs - because solving these problems requires a shitload of effort and dedication, and money is one of the best incentives for developers to do dirty and shitty work when they can do something more interesting :)

 


In Topic: Eclipse parser/autocomplete not recognizing opengl functions? Any alternative...

29 March 2013 - 04:57 AM

The difference is that you use the system-provided glext. When you use the one provided by the official web site, at least on my machine, Eclpse works perfectly. Plus, cross-platform is not a problem - this hack would be enabled only in debug builds. Plus, if it is cross-platform, VS most definitely handles this, and I would find it surprising if XCode didn't work with glew (meaning that if a platform-specific issue comes up, you can effortlessly work in native environment, and use VIM in linux for the major dev effort).


In Topic: Eclipse parser/autocomplete not recognizing opengl functions? Any alternative...

28 March 2013 - 04:53 PM

Hmm, OK, I've conducted some research on the issue, and as I suspected, somebody (GLEW) actually uses macros tongue.png This is more than what CDT obviously can handle smile.png

Since I'm no longer a hard-core linux user, I've installed the "classic" Eclipse from the web site on Ubuntu, then added the CDT via p2. This is my "lame" code I'm testing with:

 

#include <GL/glew.h>
#include <GL/glfw.h>
#include <iostream>

int main(int argc, char** argv) {
    if (argc == 2) {
        glBindBuffer(GL_ARRAY_BUFFER, -1);
    }
    std::cout<<"compiles"<<std::endl;
    return 0;
}

First, it does compile. OGL 1.x functionality can be found (e.g. glBegin(), glVertex2f()...), because it is quite easily defined in glew.h:.

 

GLAPI void GLAPIENTRY glBegin (GLenum mode); 

 

Now, if we get to the definition of glBindBuffer, which is:

 

#define glBindBuffer GLEW_GET_FUN(__glewBindBuffer) 

.. whch leads us to

~ grep "#define GLEW_GET_FUN" /usr/include/GL/glew.h
#define GLEW_GET_FUN(x) x 
~ grep "__glewBindBuffer;" /usr/include/GL/glew.h
GLEW_FUN_EXPORT PFNGLBINDBUFFERPROC __glewBindBuffer;
~ grep "#define GLEW_FUN_EXPORT" /usr/include/GL/glew.h
#define GLEW_FUN_EXPORT
#define GLEW_FUN_EXPORT GLEWAPI
(we can safely assume it's nothing on Linux)
~ grep "PFNGLBINDBUFFERPROC" /usr/include/GL/glew.h
typedef void (GLAPIENTRY * PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer);
GLEW_FUN_EXPORT PFNGLBINDBUFFERPROC __glewBindBuffer;
(we are searching for the first one.. which is the function signature)

hmm. A lot of #define and typedef magic smile.png Most C++ parsers would die at the very first define smile.png Let's see if we can cheat, though tongue.png

 

Now that we know that the problem is (MACROS), we ca implement a hack. First, go off and download your personal copy of glext.h from http://www.opengl.org/registry/api/glext.h. Place it in your project's root directory. Now, let's change the source of our little hack to:

 

#define GL_GLEXT_PROTOTYPES
#include <GL/gl.h>
#include "glext.h"
#include <iostream>

int main(int argc, char** argv) {
    if (argc == 2) {
        glBindBuffer(GL_ARRAY_BUFFER, -1);
    }

    std::cout<<"compiles"<<std::endl;
    return 0;
}


Now, that DOES compile, however I can't verify that it will run (as I'm not really an OGL person, and it's quite too late to write an example). However, if it does run with GLEW, it should run that way, too, provided you still link to the same libraries. I know, it is an ugly hack, but it does work. I haven't spent the time to test whether it works on other IDEs (QtCreator and KDevelop). Hope that helps.


PARTNERS