Categories
C++ Tutorial

C++ Variant Type Walkthrough

Considering the amount of pain I had trying to work out how to do this; I thought I’d write up something lengthy to explain how it works. It also helps me find if there’s anything in it that I don’t fully understand, else I wouldn’t be able to explain it.

The full Variant types header file has already been posted. This is the code I’m going off of.

Categories
C++

A Recursive Variant Type in C++

Because one of my goals is to rely on as few external libraries as possible, I am not using Boost. As a result, there comes times when I need to roll my own, extremely useful, library-like code that isn’t a part of the C++ standard yet.

One of these, is the Variant. A tagged union / discriminated union / sum type, that allows you to store multiple data types in one section of memory. A sort of type-erasure gimmick.

I need a type like his for two reasons so far. The first is that my scripting language, space script, is quasi-type safe. You define variables using your usual data types, but any variable type can be cast to any other type.

I did it this way mostly because I was curious to see how a language like that would behave. Probably not the best idea.

I’ve also allowed my Variant type to be recursive. This means that it can contain members of itself. I’ve done this specifically because my data format, space format, is JSON-esque, and basically every node can contain any number of numbers, strings and other objects etc. That’s the second reason I need a variant type.

This took me quite a bit of screwing around to get right. A lot of the code for the base Variant was taken from someone else’s code that I found online. This code was fundamentally broken though; so I’ve fixed it up and allowed for recursion.

I’ll probably do a write up on this at some point. I like it over the boost::variant primarily because I don’t want a never-empty guarantee. I can’t imagine why I’d want a type that doesn’t allow for null-states.

EDIT: Fixed up some of that code.

EDIT 20/05/2016: Fixed up some more of that code.

Categories
Scripting User Interface

Coupled the scripting engine with the UI engine

I’ve now managed to get the scripting engine working with the UI engine. This means that the UI can now be completely defined outside of the game-code, in run-time language files. Should result in quick changes to the game UI when it comes to it; and even modding etc.

Categories
Uncategorized

Back

Back from a break.

Categories
User Interface

Back onto the UI – Flowcharts

Now that my scripting language appears to be complete, it’s back onto the UI programming. Most of it is there, one thing remaining is the “Flowchart”.

It’s not exactly a flowchart widget, more like a “nodes” widget.

flowchart

The idea is the eventually you’d be able to add new nodes, connect and disconnect them as you see fit. Each node also contains a function; the purpose if that you can send data from one end to the other; much like my uncompleted noise-machine.

Eventually, you’d be able to use it for things like displaying a tech-tree; except the Player won’t be able to modify it.

Anyway; it’s not clear from a screenshot, but that above runs at about 25fps on my machine. Completely unacceptable. To be fair there is about 198 individual rectangle draw calls there… it doesn’t seem like it should be slowing things down; but it is.

I need to look into why it’s slowing things down so much; and if it’s just because I’m hitting a bandwidth limit; then it’s time to look into batching the draw calls (which I really should have done from day 1). Hopefully the entire UI can be knocked down to a single draw call. Or if I think about it correctly, maybe I could draw just to a texture, or individual widgets as textures to save some calls.

Categories
Scripting SpaceEngine

Arrays Completed 100%

I’ve now implemented the .size operator for arrays

Categories
Scripting SpaceEngine

Arrays Completed 75%

Arrays can now be declared separately from it’s definition. So

will now work.

I’ve also added two new operators; “array push front”, which looks like
-> , and “array push back” which looks like <- . The idea is that it’s pointing from the left to the left-most element, meaning push front and the alternative pointing from the right to the right-most element.

Next; because arrays are now effectively dynamically sized, I need some inherent way to find the size of an array. Like a .size  member or something…

Categories
Scripting SpaceEngine

Arrays Completed 50%

I’ve now finished implementing arrays in my scripting language. For now, they’re not dynamically sized, and they need all their arguments when first created.

I.e. you need to write:

You can’t write

You can otherwise access array elements and update them as necessary. All regular automatic type conversion is handled. So:

Will work. However, it does it a bit of a round-about way. The first element in an array value, everything between the {  and }  is used to determine the type of the array. In the above case it’s a string array.

Then, each subsequent element is type-converted to this type. So this becomes an array of strings.

Then the assignment of a string array value to an int array variable will cause a conversion from a string array to an int array.

If the first element was an int and not a string, only the first conversion takes place.

But, this allows me to keep the any-type to any-type conversion I wanted.

Categories
Scripting SpaceEngine

Interpreter Works

The first go at writing an interpreter for my compiled opcodes is working.

Great result. Now I basically have a working scripting engine, I just need to polish up the code and a few little bugs here and there (“-1” is read as “negative one” or “minus one”).

Categories
Scripting SpaceEngine

Scripting Language Updates

I’ve managed to put together a scripting language compiler that has the following features:

  • Native data types: bool, string, char, int + float (I need to add vector types)
  • C-like syntax
  • Functions
  • Automatic POD casting. I.e., every data type can be casted to another. This will be true even when I add classes or structs, not sure how…
  • Ability to call “Engine” functions. I.e., you seed the Compiler with possible function calls that can be made of the platform

The compiler converts something like:

Into:

Which should be very simple for a Virtual Machine to run through and execute. You can see that no optimization has taken place; I’ll probably think about doing that after getting it to actually run.