Content

Writing new code so that you can write old code faster (programming)

Page is part of Articles in which you can submit an article

written by owen on 2017-Jul-18.

related image

Recently I came up a situation while programming which required me to choose between passing a reference pointer to a structure or building a loop. Usually I would avoid pointer referencing but in this case I found that deferring the loop structure into another function ment that I could centralize all my loops into one place - speeding up my dev cycle.

Its not all wine and roses

This of course ment that I have to pass pointers to a shared structure which is a whole other can of worms involving putting things in a bucket and making sure that the bucket did not overflow or become randomly de-referenced at runtime.

But when I look at it I could escape one headache for a lesser headache and I would come out with a net positive headache in the end.

Let me explain a little more. I originally had this;

tree_list = get_my_stuff( 'tree', x, y, z );
foreach( tree_list as item ) {
draw_tree(item);
}

This worked fine until the grouping of the list got more complicated;

tree_list = get_my_stuff( 'tree', x, y, z );
foreach( tree_list as item ) {
draw_tree(item);
}
grass_list = get_my_stuff( 'grass', x, y, z );
foreach( grass_list as item ) {
draw_grass(item);
}

I needed more complicated things that did different tests and I needed to do frustrum culling and many different draw_XXXX() functions that also needed to be created and called in different places. I certainly could not continue down the road as I was heading. In programming you always have to be looking for a better/faster way of doing tasks and even if the code you are writing actually works you have to be able to balance you present success with future headaches;

tree_list = get_my_stuff( 'tree', x, y, z );
foreach( tree_list as item ) draw_tree(item);

grass_list = get_my_stuff( 'grass', x, y, z );
foreach( grass_list as item ) draw_grass(item);

forest_list = get_my_stuff( 'forest', x, y, z );
foreach( forest_list as item ) {
        tree_list = get_my_stuff( 'tree', x, y, z );
        foreach( tree_list as item ) draw_tree(item);

        grass_list = get_my_stuff( 'grass', x, y, z );
        foreach( grass_list as item )        draw_grass(item);
}

Even with clever code shortening skills you probably can see that no good will come of this. The actual code involved in draw_tree() is even more complicated that what can be shown here. Where drawing a tree I have to figure out the distance, height, position on the ground and a whole bunch of other values which are different for everything that I want to draw or hide.

I don't know if this a new trend but I was looking for ways to avoid deep looping and stumbled across this question on stack in which the programmer is trying to back-port modern high level shortcuts to C++. Clearly ignorant to the fact that it's reduces code flexibility. But what's really funny is how he "feels" that he is doing something wrong by using a for loop with a condition. Lol

Could we be mind fucking these new programmers into thinking that code style, frameworks and tab vs spaces is more important than actually writing simple and efficient code?

But anyway back to the issue at hand. The code though simple and clear was only going to get more nutty as time went by and I had to be copy and pasting all the tree drawing code every time I wanted to draw a forest, meadow, savanna or bush. What to do?

In comes global lists and reference pointers

So I figured I should start using one list for each thing that had a specific draw_XXXX() function. If I had trees - no matter where there were I would just put them into one list and draw all of them in one big loop;

get_my_stuff_loop( &tree_list, 'tree', x, y, z );

get_my_stuff_loop( &grass_list, 'grass', x, y, z );

get_my_stuff_loop( &forest_list, 'forest', x, y, z );
foreach( forest_list as item ) {
        get_my_stuff_loop( &tree_list, 'tree', x, y, z );
        get_my_stuff_loop( &grass_list, 'grass', x, y, z );
}

foreach( tree_list as item )        draw_tree(item);
foreach( grass_list as item )        draw_grass(item);

To a novice coder this might seem like a genius plan but its not obvious that I have to do more work in the background to make sure that the get_my_stuff_loop() function did not run out of control and crash the system. Previously I could because of the nature of the individual loops I could tailor each list to the specific needs of the items I wanted to store in them. e.g. forest[4]. tree[20], grass[1000]. By making a generic loop I loose the control I had. Now I have to have a generic list array that can store every possible type of object. list_array[2000]. Which means that anytime I create something new I will have to allocate a big chuck of memory to it.

Even more so certain types of objects behave differently at certain distances like grass can be hidden when at a distance. All these issues were easily managed in the individual loops because I knew exactly what and where I was drawing so I could skip things that I felt no one would notice. I could skip every second tree ( 2 % i == 0) if I felt that they were far enough away that no one would notice.

Conclusion

With the new code I will need to send more parameters so that I can try to implement some of my old tricks;

get_my_stuff_loop( &the_list, type_name, x, y, z, level_of_detail, density, parent_id, x_size, y_size, z_size );

But its not all bad right? I can code up new objects at a rapid pace with almost half the code. I swapped out simplicity for quicker iteration while wasting a bunch of memory on big generic arrays. Hopefully everything is able to fit in RAM when I am done coding. The key take away is that in the initial phase I kept my structures as simple as possible so that I could work on the difficult features inside the draw_XXXX() functions. Once those were mastered I moved to the higher level functions and at that point I needed to ramp up the pace at which I coded. The only way I could do that is by hiding as much of the nitty gritty as possible. Lets hope I do not hit up and too many edge cases.

permanent link. Find similar posts in Articles.

comments

    Comment list is empty. You should totally be the first to Post your comments on this article.


comment