ID:352576
 
I can't post on the dir2text() thread, so I'll post here:

The proc shown in that thread should detect errors and only return a distinct value. An empty string makes the most sense. The developer calling dir2txt can check for the distinct error value and handle the situation however they'd like. This is similar to how findtext() returns 0 when the string isn't found - the event that happens when the string isn't found is up to you.

You also don't need to check for invalid values. BYOND might not produce direction values like 7 (NORTH + SOUTH + EAST) on its own but that doesn't make it an invalid direction. You can use direction values like that for your own purposes. You may event want to support values like 19 (16 + NORTH + SOUTH).

Here are three methods with code to profile each one. For 200,000 calls to each proc, the total times were:

dir2txt_1: 0.532 seconds (2.660 μs per call)
dir2txt_2: 0.393 seconds (1.965 μs per call)
dir2txt_3: 0.203 seconds (1.015 μs per call)

#define DEBUG

proc
dir2txt_1(d)
if(d == 1)
return "NORTH"
else if(d == 2)
return "SOUTH"
else if(d == 3)
return "NORTH+SOUTH"
else if(d == 4)
return "EAST"
else if(d == 5)
return "NORTH+EAST"
else if(d == 6)
return "SOUTH+EAST"
else if(d == 7)
return "NORTH+SOUTH+EAST"
else if(d == 8)
return "WEST"
else if(d == 9)
return "NORTH+WEST"
else if(d == 10)
return "SOUTH+WEST"
else if(d == 11)
return "NORTH+SOUTH+WEST"
else if(d == 12)
return "EAST+WEST"
else if(d == 13)
return "NORTH+EAST+WEST"
else if(d == 14)
return "SOUTH+EAST+WEST"
else if(d == 15)
return "NORTH+SOUTH+EAST+WEST"
else
return ""

dir2txt_2(d)
if(d & NORTH)
if(d & SOUTH)
if(d & EAST)
if(d & WEST)
return "NORTH+SOUTH+EAST+WEST"
else
return "NORTH+SOUTH+EAST"
else
if(d & WEST)
return "NORTH+SOUTH+WEST"
else
return "NORTH+SOUTH"
else
if(d & EAST)
if(d & WEST)
return "NORTH+EAST+WEST"
else
return "NORTH+EAST"
else
if(d & WEST)
return "NORTH+WEST"
else
return "NORTH"
else
if(d & SOUTH)
if(d & EAST)
if(d & WEST)
return "SOUTH+EAST+WEST"
else
return "SOUTH+EAST"
else
if(d & WEST)
return "SOUTH+WEST"
else
return "SOUTH"
else
if(d & EAST)
if(d & WEST)
return "EAST+WEST"
else
return "EAST"
else
if(d & WEST)
return "WEST"
else
return ""
return ""

dir2txt_3(d)
switch(d)
if(1)
return "NORTH"
if(2)
return "SOUTH"
if(3)
return "NORTH+SOUTH"
if(4)
return "EAST"
if(5)
return "NORTH+EAST"
if(6)
return "SOUTH+EAST"
if(7)
return "NORTH+SOUTH+EAST"
if(8)
return "WEST"
if(9)
return "NORTH+WEST"
if(10)
return "SOUTH+WEST"
if(11)
return "NORTH+SOUTH+WEST"
if(12)
return "EAST+WEST"
if(13)
return "NORTH+EAST+WEST"
if(14)
return "SOUTH+EAST+WEST"
if(15)
return "NORTH+SOUTH+EAST+WEST"
else
return ""

mob
verb
test_1()
for(var/i = 1 to 25000)
dir2txt_1(i % 16)

test_2()
for(var/i = 1 to 25000)
dir2txt_2(i % 16)

test_3()
for(var/i = 1 to 25000)
dir2txt_3(i % 16)
I never imagined that there would be such a big performance difference between a switch and a series of elseif statements.

The reason why NORTH&SOUTH and NORTH&SOUTH&EAST and so forth are considered invalid directions in the other thread is because they are relatively meaningless in most contexts.
What does it mean if the direction from one object to another is NORTH&SOUTH?
What does an object facing the direction NORTH&SOUTH look like?

There's only one context where such directions make any sense, and it is with "autojoining" atoms.
In response to D4RK3 54B3R
D4RK3 54B3R wrote:
There's only one context where such directions make any sense, and it is with "autojoining" atoms.

Autojoining tiles is hardly the only use. Off the top of my head...

For a tower defense kind of game you can create tiles that contain pathing information. You give a turf a direction like NORTH+SOUTH+EAST and when an enemy steps on it, it switches their dir to either NORTH, SOUTH, or EAST.

You can store the directions a mob is trying to move in. If a player is holding left and right, this value would be EAST+WEST.

You can use the arrow keys to enable a shield around the player (for some kind of shooter, maybe). If you're pressing up and down the value is NORTH+SOUTH, meaning you're shielded from both of those directions.

Edit: I thought of another use for these kinds of directions.

If you wanted to make the edges of turfs act dense (ex: fences) so that neighboring turfs are both non-dense, but the player can't move between them, you could use a value such as NORTH+SOUTH+WEST to indicate the valid directions which you may enter a turf from.