LINQ for C++ with cpplinq

4. April 2014

 

When it comes to programming languages, I literally use dozens, but when it comes down to an all other things being equal decision my go to language of choice tends to be C#.  One of the big plus sides of C# is the wonderful LINQ ( Language Integrated Query ).  LINQ makes heavy use of lambda (closures) a feature lacking until recently in C++.  Now with lambda expressions part of the C++ language LINQ for C++ is now a possibility.  It exists as a single hpp file you add to your project.

 

If you aren’t already familiar with LINQ, here is a simple example in C#.  It’s a simple scoreboard that sorts the results by name, then by score, then totals and averages all of the scores.  As you can see, it’s a very compact and clean way to access data.

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Entry
    {
        public Entry(string name, int score)
        {
            this.name = name; 
            this.score = score;
        }

        public string name { get; set; }
        public int score { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            List<Entry> scoreEntries = new List<Entry>();
            scoreEntries.Add(new Entry("mike", 42));
            scoreEntries.Add(new Entry("bob", 99));
            scoreEntries.Add(new Entry("doug", 99));
            scoreEntries.Add(new Entry("steve", 12));

            var sortedByName = scoreEntries.OrderBy(item => item.name).ToList();
            Console.WriteLine("Sorted by score");
            sortedByName.ForEach(item => { Console.WriteLine(item.name + " " + item.score); });

            Console.WriteLine("\nSorted by name");
            var sortedByScore = scoreEntries.OrderBy(item => item.score).ToList();
            sortedByScore.ForEach(item => { Console.WriteLine(item.name + " " + item.score); });

            var totalOfScores = scoreEntries.Where(item => item.score > 0)
                .Sum(item => item.score);

            var averageScore = scoreEntries.Average(item => item.score);
            Console.WriteLine("\nTotal of scores == " + totalOfScores + " Average Score == " + averageScore);

            
        }
    }
}

 

Now let's take a look at the C++ version using cpplinq:

#include <string>
#include <list>
#include "cpplinq.hpp"
#include <iostream>


class Entry{
    public:
        Entry::Entry(std::string name, int score){
            this->name = name;
            this->score = score;
        }

        std::string name;
        int score;
};


int main(int argc, char **argv)
{
    std::list<Entry> scoreEntries;
    scoreEntries.push_back(Entry("mike", 42));
    scoreEntries.push_back(Entry("bob", 99));
    scoreEntries.push_back(Entry("doug", 99));
    scoreEntries.push_back(Entry("steve", 12));

    using namespace cpplinq;
    
    auto sortedByName = from(scoreEntries)
        >> orderby_ascending([](const Entry & entry){ return entry.name;  })
        >> to_vector();
        
    auto sortedByScore = from(scoreEntries)
        >> orderby_descending([](const Entry & entry){ return entry.score;  })
        >> to_vector();

    std::cout << "Sorted by name" << std::endl;
    from(sortedByName)
        >> for_each([](const Entry & entry){ std::cout << entry.name << " " << entry.score << std::endl; });

    std::cout << std::endl << "Sorted by score" << std::endl;
    from(sortedByScore)
        >> for_each([](const Entry & entry){ std::cout << entry.name << " " << entry.score << std::endl; });

    auto totalOfScores = from(scoreEntries)
        >> select([](const Entry & entry){ return entry.score; })
        >> sum();

    auto averageScore = from(scoreEntries)
        >> select([](const Entry & entry){ return entry.score; })
        >> avg();

    std::cout << std::endl << "Total of scores == " << totalOfScores << " average score == " << averageScore << std::endl;
    return 0;
}

 

A few obvious differences.  Cpplinq statements start with the from methods defining the type of data source to perform on.  In this case I used the default from() which takes a standard C++ STL type.  There are also from__array() and from_range() for working with arrays and iterators respectively.  Next the . (dot) operator has been replaced with the >> operator.  Of course the lambda syntax is different as well ( C++’s is much uglier ), otherwise at the end of the day, it is very similar to LINQ in both look and execution.

 

If you are new to C++ and are struggling to wrap your head around the uses for lambdas, give cpplinq a shot and you will quickly see their value!

Programming




HOLY CRAP! MOAI isn’t dead! In fact, they just released v1.5

27. March 2014

 

Wow, I gotta say this announcement pretty much broadsided me.  I wrote Moai off for dead, which was a huge shame, as I did a tutorial series on the subject, and frankly found MOAI to be some of the cleanest C++ code I had ever read.  So to hear of a new release certainly makes me happy.

image

So then, what’s new?

 

Feature merge from Zipline:

  • Massive rework of the garbage collection system to simplify object tracking
  • Reworking of the AKU Modules API
  • New SDL host to complement the GLUT host
  • A flag to MOAIAction to disable auto-stop on no children

A New Build System:

  • The CMake build system that was in place for the linux and blackberry hosts was extened to include all hosts
  • Luajit support was added to all platforms (via cmake scripts)
  • create-project-* scripts were created that allows you to generate vs2008->vs2013 and xcode project files.
  • Changes to a project can be recorded once in the relevant cmake script and all platforms should work instead of maintaining 6+ build configs
  • Plugin support was added for installing modules which are outside the moai sdk (other repos) [More]
  • Custom host support was added for compiling a host outside of the repo [More]
  • Support for compiling with Ming-w64 for a completely open source experience on Windows (no more vcruntime to distribute)

Additional Features:

  • Vector Pathfinding (MOAIVecPathGraph)
  • Box2D Closest Raycast Exposure
  • Twitter support in android
  • MOAIShader was enhanced with the 4x4 matrix and given access to UNIFORM_WORLD_VIEW
  • A faster and smoother android host with working keyboard support.
  • MOAISafariIOS is now MOAIBrowserIOS and MOAIBrowserAndroid added
  • Visibility can now be inherited!
  • Google Play Services
  • Updated Tapjoy and Vungle
  • MOAISim showCursor and hideCursor support
  • Documentation improvements
  • Chartboost for IOS and android
  • You can now EnqueueJoystickEvent from the host.
  • New HTML/JS host based on emscripten

Fixes:

  • Android logging support repaired
  • VFS works correctly on all platforms
  • A heap of lua stack overflows
  • Fixes to JSON parser and encoder
  • Textbox string bounds calculations fixed
  • PVR support working now

 

Certainly some nice new features in there, and hopefully this new release will breath renewed life into this project that frankly always deserved a better fate.

 

You can access the MOAI source code here.

You can read a more complete release notes here.

News, Programming ,




Want to use LibGDX but hate Eclipse? Good news, with Gradle IntelliJ just became easier

26. March 2014

 

I am a big fan of LibGDX and a big hater of Eclipse.  This always put me in a bit of an awkward situation, as in order to use LibGDX you basically had to use Eclipse, at least if you wanted cross platform support.  You could get IntelliJ to work, but it required a heck of a lot of jumping through hoops.  The reason Eclipse was basically forced upon you is because Google tied it’s tools pretty heavily to the Eclipse platform.  So if you want to use GWT ( for HTML target ) or Android, Eclipse was by far the easiest path.  Fortunately LibGDX recently announced they moved their build system to Gradle. 

 

Now let’s take a look at how you create and execute a LibGDX project in Eclipse.  First and foremost, grab a new release of LibGDX.

 

Next we want to generate our project.  You need gdx-setup.jar, you can download it here or find it in the lightly release of LibGDX.  Simply double click the jar to run it.  You can also run it from the command line, but we will only use the GUI in this example.

 

image

 

It’s like a stripped down version of the old setup tool, enter the name, package and class name ( following Java naming rules ) and click generate.

 

Configuring Android

 

You need to have the Android SDK installed to continue.  I recommend installing the stand-alone version of the SDK instead of the ADT bundle ( which is Android SDK + Eclipse ).  You can download the Android SDK here.  The download can be a bit tricky to located, Scroll down and locate “DOWNLOAD FOR OTHER PLATFORMS”, then locate SDK Tools only and download the appropriate package:

 

image

 

Extract that archive somewhere. 

At this point ( I am not sure its required, but it’s a good idea ), set the environment variable ANDROID_HOME and point it to this folder.

 

Now open up this folder and located SDK Manager:

image

 

Run it.  Let it install/un-install whatever it wants to do to make sure you are current.

 

The next step is very important.  You need to install the build tools version that LibGDX expects.  Right now I believe that version is 19.0.3.  The Gradle build process will fail if these tools are not installed.

image

 

 

Configuring IntelliJ

 

Make sure you have version 13 or higher.  You can download it here.  Community edition is fine, in fact, not much of the paid version is of use to a game developer.  Download and install IntelliJ 13.x if you haven’t already.

 

Anyways, now that we have fired up IntelliJ, we have a bit of configuration to do before we continue.  We need to setup our JDK and Android SDK in IntelliJ.  If you haven’t already, install and configure the Java 7 JDK.

 

This part is going to be a bit awkward, but it should only happen the first time.

 

Run IntelliJ.

In the welcome dialog, select Import Project

image

 

Navigate to the directory you created your project in earlier and select build.gradle from the root directory:

image

 

Click OK.

In the next dialog, accept the defaults and click OK.

image

 

Gradle is now going to build your project… or at least try.

Gradle downloads all the required components, so this could take a while.   Or it should, but truth is, its going to explode in a horrible state of explosionness.  Look for an error like this;

image

 

Don’t worry over much, it’s just that IntelliJ doesn’t have a clue where your JDK and ADK are.  Let’s fix that now.

 

In the Project View (ALT + 1 if missing), right click the root project and select Open Module Settings:

image

 

In the resulting dialog select SDKs then click +.

image

 

Select JDK

image

 

Navigate to the location you installed your JDK.

 

Next click + again, and this time select Android SDK.  Select the Android SDK location and click OK.

This time you also have to pick the version:

image

 

Now there is a possibility you have a wrongly configured JDK at this point too:

image

If you have an entry other than the ones you created, select it and then hit the – button.

 

OK, SDK’s are now configured.

 

Now lets re-import the project.  Select File->Import Project and pick the .build file in the root of your project again.  When prompted:

image

Select “This Window”.

 

Now your project should load without errors.  You should never have to perform the above steps again, unless you change JDK or Android SDK versions.

 

Running the Desktop Project

 

You have a one time configuration to run each project type.  Let’s start with the Desktop project:

Select Run->Edit Configurations…

image

 

If an entry for Desktop doesn’t already exist, select the + icon.

image

 

Select Application:

image

 

Now configure the project like so.  Name it then select DesktopLauncher as the Main Class, the Android\assets folder for the working directory and desktop for the classpath value.

 

image

 

Once again, its very important when selecting the working directory, make sure to select the assets folder in the android project!

image

 

Now select Run->Run Desktop and voila:

image

 

Running the Android Project

 

Once again select Run->Edit Configurations.

If an Android project doesn’t exist, select the + icon and select Android Application.

image

 

In the configuration, name it, select Android for module and optionally pick USB Device under target device.  Unless of course you are crazy enough to actually use the horrific Android emulator that is!

image

 

Now select Run->Run Android to run on an Android device.  The application will be deployed to your device and you should see Logcat information in IntelliJ

 

image

 

Running the iOS Project

 

Ok… you need a Mac to do this part and I don’t currently have my Mac with me.  So… coming later.

 

 

Running the GWT ( HTML ) Project

 

If there is an area you are going to have trouble with, this is the one.  It’s somewhat normal though, I’ve had a lot of fights with GWT tooling thus far.

 

The project is the same Run->Edit Configurations:

This time select Gradle as the project type.

image

 

Now configure the following, set the Name, select the gradle project ( details below ), click Single Instance Only and task to superDev:

 

image

 

When setting the gradle project, be sure to select the project in the gwt folder.

image

 

Now click Run->Run HTML.

 

It will churn away for a few moments, then you should see:

image

 

Look for the URL in the results.  Open this in a browser to run your app.

 

In all honesty, this currently simply doesn’t work for me right now.  Currently I get:

image

 

Frankly I have had nothing but trouble with GWT and superDEV, so I really cant be bothered fixing this at the moment.  If I do come up with a solution, I will post it here.

 

EDIT

Ok, I have a solution to the GWT problems, and it was mostly me, but partially a lack of intuitiveness.

To see your application, once you run the project open a browser window and go to localhost:8080/gwt

Then you should see:

image

 

There you now have a working project running in IntelliJ now.  Much of that was one time, so at the end of the day, after the first time, setting up a new project in IntelliJ is just as fast as an Eclipse one.  YAY, no more Eclipse!

Programming ,




LibGDX Tutorial 10: Basic networking

11. March 2014

 

We are going to look at networking for your LibGDX application.  Networking in LibGDX is relatively primitive, supporting only socket communications.  In many cases though, that’s more than enough.  We are going to implement a very simple socket based chat application.  The code is heavily commented, so the discussion will actually be pretty sparse.  If I missed something please leave a comment and I will do my best to address it.

 

Alright, let’s jump right in with the code:

package com.gamefromscratch;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Net.Protocol;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.net.ServerSocket;
import com.badlogic.gdx.net.ServerSocketHints;
import com.badlogic.gdx.net.Socket;
import com.badlogic.gdx.net.SocketHints;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.TextArea;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.ui.VerticalGroup;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;

public class Networking implements ApplicationListener {
    private OrthographicCamera camera;
    private SpriteBatch batch;
    private Skin skin;
    private Stage stage;
    private Label labelDetails;
    private Label labelMessage;
    private TextButton button;
    private TextArea textIPAddress;
    private TextArea textMessage;
    
    // Pick a resolution that is 16:9 but not unreadibly small
    public final static float VIRTUAL_SCREEN_HEIGHT = 960;
    public final static float VIRTUAL_SCREEN_WIDTH = 540;
    
    
    @Override
    public void create() {        
        camera = new OrthographicCamera(Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
        batch = new SpriteBatch();
        
        // Load our UI skin from file.  Once again, I used the files included in the tests.
        // Make sure default.fnt, default.png, uiskin.[atlas/json/png] are all added to your assets
        skin = new Skin(Gdx.files.internal("data/uiskin.json"));
        stage = new Stage();
        // Wire the stage to receive input, as we are using Scene2d in this example
        Gdx.input.setInputProcessor(stage);

        
        // The following code loops through the available network interfaces
        // Keep in mind, there can be multiple interfaces per device, for example
        // one per NIC, one per active wireless and the loopback
        // In this case we only care about IPv4 address ( x.x.x.x format )
        List<String> addresses = new ArrayList<String>();
        try {
            Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
            for(NetworkInterface ni : Collections.list(interfaces)){
                for(InetAddress address : Collections.list(ni.getInetAddresses()))
                {
                    if(address instanceof Inet4Address){
                        addresses.add(address.getHostAddress());
                    }
                }
            }
        } catch (SocketException e) {
            e.printStackTrace();
        }
        
        // Print the contents of our array to a string.  Yeah, should have used StringBuilder
        String ipAddress = new String("");
        for(String str:addresses)
        {
            ipAddress = ipAddress + str + "\n";
        }
        
        // Now setupt our scene UI
        
        // Vertical group groups contents vertically.  I suppose that was probably pretty obvious
        VerticalGroup vg = new VerticalGroup().space(3).pad(5).fill();//.space(2).pad(5).fill();//.space(3).reverse().fill();
        // Set the bounds of the group to the entire virtual display
        vg.setBounds(0, 0, VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT);
        
        // Create our controls
        labelDetails = new Label(ipAddress,skin);
        labelMessage = new Label("Hello world",skin);
        button = new TextButton("Send message",skin);
        textIPAddress = new TextArea("",skin);
        textMessage = new TextArea("",skin);

        // Add them to scene
        vg.addActor(labelDetails);
        vg.addActor(labelMessage);
        vg.addActor(textIPAddress);
        vg.addActor(textMessage);
        vg.addActor(button);
        
        // Add scene to stage
        stage.addActor(vg);
        
        // Setup a viewport to map screen to a 480x640 virtual resolution
        // As otherwise this is way too tiny on my 1080p android phone.
        stage.setViewport(VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT,false);
        stage.getCamera().position.set(VIRTUAL_SCREEN_WIDTH/2,VIRTUAL_SCREEN_HEIGHT/2,0);
        
        // Now we create a thread that will listen for incoming socket connections
        new Thread(new Runnable(){

            @Override
            public void run() {
                ServerSocketHints serverSocketHint = new ServerSocketHints();
                // 0 means no timeout.  Probably not the greatest idea in production!
                serverSocketHint.acceptTimeout = 0;
                
                // Create the socket server using TCP protocol and listening on 9021
                // Only one app can listen to a port at a time, keep in mind many ports are reserved
                // especially in the lower numbers ( like 21, 80, etc )
                ServerSocket serverSocket = Gdx.net.newServerSocket(Protocol.TCP, 9021, serverSocketHint);
                
                // Loop forever
                while(true){
                    // Create a socket
                    Socket socket = serverSocket.accept(null);
                    
                    // Read data from the socket into a BufferedReader
                    BufferedReader buffer = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
                    
                    try {
                        // Read to the next newline (\n) and display that text on labelMessage
                        labelMessage.setText(buffer.readLine());    
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start(); // And, start the thread running
        
        // Wire up a click listener to our button
        button.addListener(new ClickListener(){
            @Override 
            public void clicked(InputEvent event, float x, float y){
                
                // When the button is clicked, get the message text or create a default string value
                String textToSend = new String();
                if(textMessage.getText().length() == 0)
                    textToSend = "Doesn't say much but likes clicking buttons\n";
                else
                    textToSend = textMessage.getText() + ("\n"); // Brute for a newline so readline gets a line
                
                SocketHints socketHints = new SocketHints();
                // Socket will time our in 4 seconds
                socketHints.connectTimeout = 4000;
                //create the socket and connect to the server entered in the text box ( x.x.x.x format ) on port 9021
                Socket socket = Gdx.net.newClientSocket(Protocol.TCP, textIPAddress.getText(), 9021, socketHints);
                try {
                    // write our entered message to the stream
                    socket.getOutputStream().write(textToSend.getBytes());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    @Override
    public void dispose() {
        batch.dispose();
    }

    @Override
    public void render() {        
        Gdx.gl.glClearColor(0.5f, 0.5f, 0.5f, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        batch.setProjectionMatrix(camera.combined);
        batch.begin();
        stage.draw();
        batch.end();
    }

    @Override
    public void resize(int width, int height) {
    }

    @Override
    public void pause() {
    }

    @Override
    public void resume() {
    }
}

 

And when you run the code you should see:

image

 

The top two values are the IP v4 addresses of the machine you are running on.  You need to enter these in the other copy of the application you want to chat with.  This address uniquely identifies your machine on the internet, while we specified the port (9021) using code.  Think of a port like a mailbox at an apartment building.  The street address of the building is comparable to the IP address, while PORT is akin to the apartment number.  Port values go from 1 to 65,536, although several are reserved.  Most of the reserved ports are > 100, so when picking a port for your application look up to see if that address is a dedicated port ( such as 80 for HTTP communication, or 21 for FTP ), or simply pick a random high value.  Your machine can have multiple addresses, one per network adapter and possibly more, especially if you run virtualization software like VMWare.  Then there is the value 127.0.0.1, this is a special address known as a loop back adapter, and address that points back at itself.

 

Where it currently says “Hello World”, this is where any incoming messages will be displayed.

 

In the first textbox, you enter the IP address of machine you want to send a message to.  In this example, you can actually send a message to yourself, simply enter your own IP address.  Finally the second textbox is the text of the message to send.  Of course you send the message by pressing the Send Message button.

 

One thing you may notice from the above example is I set it to run in the oddball resolution of 540x960.  Why did I do this?  For a couple reasons.  First, the native resolution of the phone I tested on ( HTC One ) is 1920x1080 and the default Scene2D Skin/Font are wayyyyyyyy too small at that resolution.  Of course I could have created a a new skin that was more appropriate but, well, I'm lazy.  The second reason is that resolution is a decent size and is the same aspect ratio as 1080p ( 16:9 ), so it scales well, both up and down, when displayed on a 16:9 screen.  On an iPad it’s going to look like absolute garbage.  Perhaps in the future I will do a post specifically about handling multiple device resolutions.

 

There is one more thing to be aware of, this example currently will not work on iOS.  The Scene2D TextField widget currently doesn’t bring up the iOS on screen controller.  There is a fix on the LibGDX contributions forum.  It’s an iOS specific hack/workaround, so I wouldn’t expect it to be merged into the main trunk.  Finally, LibGDX built in networking is fairly simple, limited to just socket programming.  For more robust networking support check out kryonet, it supported in LibGDX and is reported to work across all LibGDX platforms except HTML5.  Which isn’t really surprising, as the author Nathan Sweet is also a LibGDX contributor.

Programming , ,




Troubleshooting LibGDX exceptions. Configuring Eclipse to be slightly less stupid.

5. March 2014

 

If you’ve been a regular reader of my blog you will probably know that I am not Eclipse’s biggest cheerleader.  “I hate it” might be a bit strong, but not by much.  Recently though, I’ve been forced to use it more and more.  Frankly, if you want to work in cross platform Java, especially using Google’s tools, you are pretty much forced to these days.  One of my biggest annoyances is the obtuseness of the interface.  Today I am going to show one such example.

 

One of the things about working with LibGDX in Eclipse is it uses a fair number of threads and when an exception is thrown, if it wasn’t directly in your code, you are kinda screwed.  Look at this example, from code I am currently working on:

 

image

 

What I see here is I caught a “Throwable” derived exception and am throwing a RuntimeException in turn.  I can look up in the thread stack trace to see where it was thrown ( although the code above makes it pretty obvious, but stay with me for a moment).

 

If I look at the debug window, I can see that stack trace, to see where the exception came from:

image

 

There is a really useful piece of information here ( the exception type was GdxRuntimeException ), but the stack trace itself is pretty flat.  That is because each stack is thread specific and frankly, we just created this thread.  So our stack basically consists of Thread.run() and well, that’s about it.  We can tell by our code that the exception was thrown somewhere in LwjglApplication.mainLoop() but that is all we’ve got to work with.  We could set a breakpoint in mainLoop and run until it triggers, but that is extremely annoying.  What we want to do instead is stop execution when the exception is THROWN, not when it is caught.

 

This can be done in Eclipse, but in the way of Eclipse, it certainly isn’t intuitive.  Since we know our exception type is GdxRuntimeException, we will trigger it to stop execution whenever one of those is thrown.  Let’s look at how.

 

In Eclipse, switch to Debug Perspective.

image

 

Now locate the Breakpoint panel and the J! icon.  ( Intuitive eh? )

image

 

In the resulting dialog, in the Choose an exception text field, enter GdxRu*.  The asterisk is a wildcard, so it will return any Exception that start with GdxRu.  Click OK.

image

 

By the way, the default is *Exception*, meaning breakpoint on all Exceptions with the word Exception in them.  That sounds wonderful and all, problem is, it simply doesn’t work… yay Eclipse.  There is probably some 5 year old bug report somewhere explaining why.

OK, bitching aside, your exception list should now contain an entry for GdxRuntimeException:

image

 

Now right click the Exception and select Breakpoint Properties…

image

 

Make sure the following settings are enabled:

image

 

Now when you run the code again, the debugger will stop where the exception is thrown.

image

Wahoo!  Now that information is about 1000x more useful.  Now we see where our Exception is actually being generated.

 

A couple tips.

You can toggle the breakpoint exception off and on using the checkbox next to it in the breakpoint window:

image

 

Remember how I said earlier that setting *Exception* as the breakpoint simply doesn’t work?  So, what do you do if you want to stop on all exceptions?  You set a breakpoint on Throwable and set “Subclasses of this Exception” to true, like so:

image

 

Warning though, Exceptions are commonly thrown, so expect hit a whole lot of breakpoints!

 

I know this information is probably common knowledge to people that live in Eclipse, but for those of us that come from other IDEs, its frustrating until figured out, and certainly not intuitive to figure out.  Thus this post, hope a few of you found it useful.

Programming ,