Sean's Coding Journal Ramblings of Sean Middleditch, Game Developer and Student

17Feb/140

Direct3D 11 Debug API Tricks

Direct3D 11 has some handy debug APIs provided that make tracking down problems much easier. Unfortunately, while the API reference is rather complete and quite useful, I haven't been able to find any good tutorials on actually using them in real code. The following are a few tips on using the API interfaces.

29Jan/143

Dangers of std::shared_ptr

I've had a lot of conversations with people lately based on their experience and my own regarding

shared_ptr

(either the C++11 standard version, the TR version, the Boost version, or home-grown versions). The almost universal conclusion has been that

shared_ptr

is best avoided in almost every circumstance when writing software of substantial size.

Filed under: C++, Software Continue reading
27Aug/133

Why C++ Does Not Need C#-like Properties

C++ is a very complex language, yet there seems to always be a little more room for even more complexity. One of the often requested features of C++ are C# properties syntax. The C# properties syntax offers two distinct advantages, the most relevant currently being something which C++ does not need (and can even be considered harmful in C# code).

Filed under: C++, Opinion Continue reading
9Aug/131

JavaScript Delegates w/ Currying Placeholders

A particularly powerful part of JavaScript is its vaguely functional aspects. However, they can at times be painful to use. The this name will rebind in surprising ways when passing around functions and there's no native way to curry parameters, though you can of course form closures.

I've written a little library that gives something akin to std::bind from C++, but with the additional benefit of supporting the this context automatically.

The usage is pretty simple.

delegate(obj, method)

delegate(this, this.method)

delegate(this, func);

Nice and simple and about as obvious and concise as you can get. One could support passing a string as the second parameter to avoid needing to specify the object twice in some cases, I suppose, but then you'd like code completion and refactoring support in the editors that have them.

Once you have a delegate, you can call it like any function and it Just Works(tm). Arguments are forwarded on as expected, the return value is returned as expected, and so on.

But wait, I've also added currying! With this feature, you can bind extra parameters to the delegate itself so they're automatically passed on. You can even use placeholders so you can mix in parameters to the delegate, change their order, or so on.

// bind a binary function delegate but swap its inputs
delegate(func, bind(1), bind(0));

// bind a trinary function as a binary function with a curried parameter
delegate(func, bind(), "foo", bind());

// bind a unary function into one that takes 6 parameters and ignore the first 5
delegate(func, bind(5));

I've found these all to be incredibly useful for event callbacks and the like while writing NodeJs code. In many cases I need to bind a callback to simply invoke some method with a static argument. In a few cases I need to support a mixture of static arguments and ones from the event callback. This delegate module lets me do all that!

There's really not much to it:

(function(){
  function binder(n) { this.index = n; }
  function bind(n) { return new binder(n); }

  function delegate(obj, cb) {
    if (arguments.length > 2) {
      var curry = [].splice.call(arguments, 2);

      var bound = false;
      for (var i = 0; i < curry.length; ++i) {
        if (curry[i] instanceof binder) {
          bound = true;
          break;
        }
      }

      if (bound) {
        return function(){
          var params = [];
          var next = 0;
          for (var i = 0; i < curry.length; ++i) {
            if (curry[i] instanceof binder) {
              var index = curry[i].index;
              if (index === undefined) {
                params.push(arguments[next++]);
              } else {
                params.push(arguments[index]);
                next = index + 1;
              }
            } else {
              params.push(curry[i]);
            }
          }

          return cb.apply(obj, params);
        }
      } else {
        return function() { return cb.apply(obj, curry); }
      }
    } else {
      return function(){ return cb.apply(obj, arguments); }
    }
  }

  module.exports = delegate;
  module.exports.delegate = delegate;
  module.exports.bind = bind;
})();

And here's a little silly bit of test code to show how it works.

var delegate = require('delegate')
  , bind = delegate.bind;

var obj = {
  a:1,
  b: 'str',
  m: function() { return this.b; },
  d: function(v,u) { return this.a + v + u; }
};
function f(v,u) { return v + u; }

function call(cb) {
  var params = [].splice.call(arguments, 1);
  console.log(cb.apply(this, params));
}

call(delegate(obj, obj.m)); // prints str
call(delegate(obj, obj.d, 1, 2)); // prints 4
call(delegate(obj, obj.d, bind(), 4), 7); // prints 12
call(delegate(obj, obj.d, 4, bind(5)), 0, 1, 2, 3, 4, 5); // prints 10

var d = delegate(obj, obj.d, bind(), bind(3));

call(d, 7, 4, 5, 6); // prints 14

d = delegate(this, f, bind(1), bind(0));

call(f, "a", "n"); // prints ab
call(d, "a", "b"); // prints ba

I note that the code could be made a slight bit prettier and more compact with the use of a helper library that extends Array with some useful methods, but I like the way the code right now has no extra module dependencies.

GitHub link: https://github.com/seanmiddleditch/js-delegate.git
NPM link: https://npmjs.org/package/js-delegate

19Jul/130

C++11 Usage of std::enable_if in Function Templates

This is just a quick post for those of you who don't already know about this.

In C++11, function templates can now have default template argument, e.g.

template <typename Type1, typename Type2 = void>
void foo();

foo<int>(); // Type1=int, Type2=void
foo<float, char>(); // Type1=float, Type2=char

Previously this was only available for class templates.

The nice thing is that this can be applied with std::enable_if, just like with class templates before. Where-as we previously had to do some kind of monstrosity like:

template <typename Type>
typename std::enable_if<condition<Type>::value, return_type>::type foo(const Type&);

We can now do the slightly cleaner and much friendlier to IDEs version:

template <typename Type, typename std::enable_if<condition<Type>::value, int>::type = 0>
return_type foo(const Type&);

If you aren't selecting a return type with meta-programming, this is much nicer. IDEs are happier figuring out the return type for you. Tools which document signatures tend to be happier. All around, it's just better. Expect C++14 to make std::enable_if a little easier to use, too.

Filed under: C++, Tips No Comments
30May/130

C++ Runtime Invocation of Bound Function via Variadic Templates

A fellow traveler in the land of C++ was attempting to perform binding of a function using variadic templates and invoking it at runtime with an array of "variant" data types. Several of our companions asserted that this was impossible with C++11. Not quite believing them, I set out to solve the problem. The following is a very simple demo made to show how this can be done.

5Apr/130

Zero-Trivial Constructors and Destructors

The C++ specification has an explicit definition of a trivial constructor (as well as a trivial copy constructor, move construct, assignment operators, and destructors). Triviality helps with a number of optimizations. Unfortunately, there are times when a constructor is "almost trivial" or when a destructor is trivial under certain circumstances. The C++ standard does not deal with this issues. I propose some simple traits that can be added to a custom framework to support these concepts and which could be added to C++ with some work.

5Jan/134

Data Structures for Game Developers: The Slot Map

Data structures are an integral part of all of computer science, and the study of data structures makes up a large portion of most students' school work. While an essentially limitless number of data structures exist, each with their own ups and downs, there are a relatively small number which find repeated, frequent use in the field. Games in particular have their own set of highly useful data structures applicable to many scenarios. Today I'm going to describe one of the simpler ones: slot maps.

30Dec/124

Experimenting with Fixed Size Delegates with User Data

A fairly common need in many programming tasks is to pass a function off to another function as a parameter. This allows all kinds of fancy higher-order functional programming. It's also really handy for event and messaging systems, particularly when building UIs. Games also make heavy use of such features, though all the peculiar requirements of games often make conventional solutions unusable.

5Aug/1210

Matrices, Handedness, Pre and Post Multiplication, Row vs Column Major, and Notations

I used to find myself needing to do a quick refresher on the different matrix notations and usage patterns in computer graphics every time I sat down to do any 3D math. I'm admittedly not a graphics expert and it took me a long while to beat this information into my head. There are a lot of articles online on the topic, but I found most of them to be incomplete or poorly written. In the interest of saving others some headaches, I decided to write up my own explanation. If you get confused by the different notations for matrices, the "right-handed" vs "left-handed" coordinate systems, pre- vs post-multiplication, or the differences between row-major and column-major matrices, read on.

   Older Entries »

Recent Articles

Categories

Archives