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!


Member Since 09 Dec 2005
Offline Last Active Apr 24 2015 01:39 AM

#5084587 EventBus - Possible with C++ templates?

Posted by Bregma on 09 August 2013 - 08:48 PM

The Handler is a function (not a class), or am I completely tripping?

Just to be clear: the handler in the code AllEightUp posted is a std::function. That means you can use any callable object, whether it's a namespace-level (free) function, a member function, a lambda expression, or a class with an overloaded operator()(). It's very very expandable.


If you just want to use inheritance to implement a Handler interface, there's nothing stopping you, even using AllEightUp's code.  Your base class can just use std::bind to connect the handler to the event.

#5083846 Is Python underestimated with what it can do?

Posted by Bregma on 07 August 2013 - 06:09 AM

In the end, I'd prefer if we could get a language that gives the control of C/C++ and the convenience of the higher level languages. I actually think it would be worthwhile to put some of the energy that's being spent on updating C++ into just developing a whole new language that gives a closer approximation to that blend. When I can get something that's very easy to code in and highly portable, but manages to be clear enough that I can predict what the native bytecode will look like, then I'll feel like we're making progress.

Actually, the Ada programming language predates the C++ language. It's lack of widespread success was due to the combined factors of tight centralized control (no vendor variants were allowed, so you could not get a subset for DOS) and the lack of underlying hardware support for some of its mandated features (for example, support for concurrently on processors that did not provide atomic operations). Oh, and it's incompatibility with existing libraries written in C.

It was like being handed the keys to a brand new Cadillac but all you had in your garage was a Vespa. Everyone rode their Vespa, and now people are debating about whether it's better to ride a Vespa or a Honda. The Cadillac is still out there, rusting away.

#5083282 calling destructor versus new object

Posted by Bregma on 05 August 2013 - 11:37 AM

Placement new is effectively a direct call to the constructor. You can also call it directly like any other member function.

No it's not and no you can't.

When an object is constructed, even using placement new, more than just the constructor body is invoked. Yes, if you have a simple class without any kind of inheritance in which all its members are PODs and there is no initializer list, and you aren't using exceptions or RTTI anywhere in your application, placement new is effectively the same as calling the constructor like a function but using a weird syntax. That's a pretty broad range of restrictions to say placement new is effectively a direct call to the constructor. It's more accurate to say "constructing and object using placement new is a way of constructing an object, and one of the things that happens when an object is constructed is that the constructor is invoked."

A conformant compiler will not allow a constructor to be invoked directly since it does not have a name and does not participate in name lookup (see [12.1](2) of the standard) -- it should result in a compile-time error.

#5083104 calling destructor versus new object

Posted by Bregma on 04 August 2013 - 04:29 PM

Hey, you can't call a constructor.  You can construct an object (in which case the constructor gets invoked), but the C++ language provides no way to call a constructor directly.


If you're doing what I think you're doing, you're probably invoking the destructor directly (which is, technically, undefined behaviour for objects not created using placement new) and then calling an initializer function to reset the object values.  The proper way to do that in C++ is to use the assignment operator to assign a new object value to the existing object instance.


For example:

Engine_d3drenderer::CD3dscene    _d3dscene;
// ... use the scene
_d3dscene = Engine_d3drenderer::CD3dscene(); // destroy the old object and assign a new, freshly initialized value

#5083102 Used old C++, Sudden feeling overwhelmed.

Posted by Bregma on 04 August 2013 - 04:11 PM

I can get the gist of exception handling down, but I don't see a practical use... What was wrong with return values to handle errors?

I really strongly recommend getting a copy of "The C++ Programming Language" by Stroustrup.  He explains why and when you would make such a choice, and the relative advantages and disadvantages.  He also points out it's OK to program using "C with Classes."  You need to own a copy of that book, it's like the bible only without all the begats (that's in a separate book by Stroustrup, the "Design and Evolution of C++").


Also, Guru of the Week.

#5082740 list of vectors

Posted by Bregma on 03 August 2013 - 07:33 AM

SDatabase::getIls() expects a pointer to a StdWaypointList and you're passing a StdWaypointList by value.  Bizarrely, that what the error message tells you.  Good things, error messages.


You'll also need to fix your return value -- you don't have one, but you use it. 

#5082739 Is Python underestimated with what it can do?

Posted by Bregma on 03 August 2013 - 07:27 AM

I'd like to point out that Gimp was written in C/C++, and it's quite slow at responding a lot of times.

The gimp is written in C (not C++) and is very fast.  It has a scripting extension that uses Scheme, because developing in a scripting language (like Python) is very fast compared to developing in C (in particular, the Gimp ToolKit, aka GTK).  If you find something in the gimp to be unresponsive, it's likely a scripted part, both because interpreting scripts is relatively slow and because those parts tend to do massive data processing.


The first big advantage of Python is rapid development time.  In today's world of disposable everything, the cost of a developer's time needs to be minimized so an application can get to market as quickly as possible.  Python has a lower learning curve so you can hire inexperienced, inexpensive developer monkeys to churn out code, and since the product is disposable it doesn't have to work well, it just has to get into consumers' hands quickly so money can be exchanged.


The second big advantage is the Python is Fast Enough.  Yes, it's slower than native code, but humans are slow.  When it comes to most human interaction software, you do not need the fantastic speed geeks brag about.  The parts that do need speed can be delegated to lower levels written in native code (for example, OpenGL).


Combine those two advantages, and it makes Python an excellent and recommendable choice for not only a first language when learning programming, but a go-to language for many general purposes.  It's not always the best tool for a particular job, but it's an appropriate tool for many jobs, including game development.

#5082201 pointers

Posted by Bregma on 01 August 2013 - 07:46 AM

What you really should write is virtual void appendWaypoint(Waypoint const& wpt); because then you will not run into problems with certain template and lambda syntaxes.  You would read that parameter declaration aloud as "the Waypoint const reference wpt", same as if it were spelled const Waypoint &wpt except all the words are in the same order.


The confusion over the '&' token indicating a pointer is because it is overloaded as the unary address-of operator, used to get the address of a variable (generate a pointer to the variable).  A pointer is declared using the '*' token, which is overloaded as the dereferenced-value-of operator, used to get the value addressed by a pointer.  In summary:

int an_int = 7;                            // an_int is of type int containing the value 7.
int& reference_to_int = an_int;            // reference_to_int is an alias for an_int.
int* pointer_to_int = &reference_to_int;   // the dereferenced value of pointer_to_int is of type int,
                                           // and pointer_to_int is a pointer initialized to the address of an_int.
int another_int = *pointer_to_int;         // another_int will now have the value 7.

#5081828 Which Of These 3 API Combinations Would You Advise (GUI's)?

Posted by Bregma on 30 July 2013 - 07:36 PM

1. OpenGL + X (I'm already using OpenGL for the rendering, I already know a small bit of X programming)

2. OpenGL + SDL (SDL is more abstracted and cross platform than X, but I have never used it)

3. GTK+ (It is written in C like my program, but uses more resources and I have never used it)

1. OGL + X11 = too much nope...  detecting all the extensions, handling all the corner cases, doing backflips and handstands to use 1980s tech to do a 1990s job, no thanks.  Just choosing the right visual and obtaining the correct GLX context is painful, let alone event processing.  There's a reason why all those toolkits evolved to wrap X11 and make it entirely disappear from the API.  Very large learning curve, poor documentation, difficult to debug.


2. OGL + SDL = good choice.  Small learning curve, good documentation.  Sometimes a pain to debug.


3. GTK+ = run, don't walk away -- a massive, massive, heavyweight API in which you have to rewrite the C++ runtime in every source file, and with no upstream support (maintenance is not considered a community activity, reinventing the entire API every couple of years is where it's at). 

Very large learning curve, poor documentation, difficult to debug.


And yes, I've used all of the above.

#5076673 link libSDL2.a with cmake

Posted by Bregma on 10 July 2013 - 12:31 PM

Thanks, that was very helpful!


I did ldd libSDL2.so and it listed these dependencies.

$ ldd libSDL2.so
    linux-vdso.so.1 =>  (0x00007fff507fe000)
    libm.so.6 => /lib64/libm.so.6 (0x00007fa64d693000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00007fa64d48f000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fa64d272000)
    librt.so.1 => /lib64/librt.so.1 (0x00007fa64d06a000)
    libc.so.6 => /lib64/libc.so.6 (0x00007fa64ccb2000)
    /lib64/ld-linux-x86-64.so.2 (0x0000003b9b400000)

However, I am still unsure if I have to add the dependencies that I haven't specified in my CMakeLists.txt so that it still works with those DSO linking changes. As mentioned I had to add libpthread, libdl, and librt. Must I now add libm, libc, linux-vdso and ld-linux-x86-64?

If you want a purely static binary (no DSOs at all) then yes, you'd need to link all those libraries (save libc and the DSO interpreter, ld-linux-x86-64.so.2 and linux-vdso.so.1).  You would want to make sure you pass the relevant -static switches to the linker to get it to pick up the static versions of the runtime (libc).


I'd like to point out that you'll probably have trouble.  One of the dependencies is libdl, the dynamic library loader, which implies libSDL2 load plugins dynamically.  That will probably fail since there is no DSO interpreter to resolve the symbols at load time.  You're in for a world of pain, trying to do something the GNU system was designed explicitly to avoid.

#5076200 Why is hexadecimal used in binary model files?

Posted by Bregma on 08 July 2013 - 01:46 PM

While the numbers do look fairly arbitrary, they do seem systematic.  I'd like to point out that the code for the main chunk (0x4d4d) is 'MM' in ASCII.  Some other codes are likewise two-letter ASCII combinations, but not all are.

#5076196 Manipulating metadata in files

Posted by Bregma on 08 July 2013 - 01:41 PM

Is this "file metadata" contained in the file byte stream or is it stored externally in another file's byte stream?  Or, are you using a forked filesystem like Macintosh System 6 or a rich filesystem VMS or PrimeOS or something?

#5074427 Dealing with corrupted files in Linux

Posted by Bregma on 01 July 2013 - 06:44 AM

First of all, what exactly happens if my program gets forced to quit (by the OS), during a filewrite operation (say a loop that writex string lines)? I assume the file is just incomplete then, but can it also get corrupted by this?


You would get a truncated file.  Unless you're explicitly opening for rewrite and positioning the file pointer yourself, your file is getting overwritten, not rewritten, so it will ne get corrupted.


Second, if a file gets corrupted due a power loss, does it only affect that single file, or could there be more problems? I guess not, but when
reading about the topic they sometimes mention the whole File System getting corrupted. That sounds serious.


Non-journalling filesystems can get their metadata corrupted by an unexpected power loss.  That's exactly why journalled filesystems were introduced. In all the years I've used Linux with ext3 (and more recently ext4) filesystems I've never seen metadata corrupted by sudden and unexpected power loss.  The journalling uses a commit/rollback semantic.


Third, in case the file gets corrupted somehow, what will happen if I try to open it next time?
I want to test somehow if the file can be opened, and if its complete (maybe by putting a "EOF" as a last line).


If your data is corrupt, you'll be able to open and read the file (because the metadata is OK), but it may contain unexpected or missing data.  If the metadata is corrupt, you will probably not be able to find your file to open it.


If you really do have about a second of frantic saving before the power rails are pulled, it's likely that the OS will be able to flush any outstanding buffers.  If you are using a journalled file system (without data journalling) the worst case scenario is that your app did not send some buffers to the OS and you have some truncated files.


Remember, Linux is used on a majority of the systems running the internet and are responsible for trillions of dollars in data.  Easily millions of dollars have been spent over the years making data integrity extremely robust.  That's not to say you can't do an end-run:  most people use FAT filesystems on SD cards, where all integrity bets are off.  You might want to double-check what you're using on the SD card.

#5073645 funky looking conditional statement i think

Posted by Bregma on 28 June 2013 - 11:35 AM

Bregma is this diagram similar to your explanation of a|=b?

Indeed it is. 

#5073593 a = b = new c?

Posted by Bregma on 28 June 2013 - 08:10 AM

The assignment operator binds left, which means

a = b = new c;

is the same as

a = (b = new c);


a.operator=(b.operator=(c.operator new()));