ID:2130955
 
Resolved
locate() couldn't look up /image and its derived types by reference.
BYOND Version:511.1352
Operating System:Windows 10 Pro 64-bit
Web Browser:Chrome 52.0.2743.116
Applies to:Dream Daemon
Status: Resolved (511.1353)

This issue has been resolved.
I was doing some testing on \ref IDs and encountered this strange bug. Using the \ref macro on /image any type derived from /image will return an ID, but using that ID in locate() doesn't get back the type path.

I'm not sure what this could mean, but it's a really bad sign if these IDs are used internally. Type paths are constants, which makes this even more strange.

Run this code to clearly see the problem:
image/myimage

mob
Login()
..()
checkrefs()

verb/checkrefs(type as null|text)
set name = "check locate(\"\\ref\[/type\]\")"

if(!type)
type = /datum

var/ref,foundpath,instance,newref,newfound

for(var/path in typesof(text2path("[type]")))
ref = "\ref[path]"
foundpath = locate(ref)
if(foundpath)
src << "<tt>[ref] [foundpath] was found.</tt>"
else
src << "<tt><font color=red>[ref] [path] not found!</font></tt>"
// This is being output for any type derived from /image.
try
instance = new path
newref = "\ref[instance]"
newfound = locate(newref)
if(newfound)
src << "<tt>[ref] <font color=blue>new</font> [path] was found ([newfound]).</tt>"
else
src << "<tt><font color=gold>[ref] <font color=blue>new</font> [path] not found!</font></tt>"
catch
src << "<tt><font color=teal>[ref] cannot create <font color=blue>new</font> [path]!</font></tt>"
src << ""


As requested, here is the output this produces:
[0x3f000000] /image/myimage not found!
[0x3f000000] new /image/myimage was found ().
[0x3f000001] /image not found!
[0x3f000001] new /image was found ().
[0x20000002] /datum was found.
[0x20000002] new /datum was found (/datum).
[0x9000003] /atom/movable was found.
[0x9000003] new /atom/movable was found (the movable).
[0xa000004] /atom was found.
[0xa000004] cannot create new /atom!
[0x9000005] /obj was found.
[0x9000005] new /obj was found (the obj).
[0xa000006] /turf was found.
[0xa000006] cannot create new /turf!
[0xb000007] /area was found.
[0xb000007] new /area was found (the area).
[0x20000009] /sound was found.
[0x20000009] new /sound was found (/sound).
[0x2000000a] /icon was found.
[0x2000000a] new /icon was found (/icon).
[0x2000000b] /matrix was found.
[0x2000000b] new /matrix was found (/matrix).
[0x2000000c] /database/query was found.
[0x2000000c] new /database/query was found ().
[0x2000000d] /database was found.
[0x2000000d] new /database was found ().
[0x2000000e] /exception was found.
[0x2000000e] new /exception was found (/exception).
[0x2000000f] /regex was found.
[0x2000000f] cannot create new /regex!
[0x3f000010] /mutable_appearance not found!
[0x3f000010] new /mutable_appearance was found ().
[0x8000000] /mob was found.
[0x8000000] new /mob was found (the mob).

Compile and run to see it all fancy and colorful.
This isn't a bug.

Your first \ref is a reference to the type /image; types can't be locate()'d as far as I'm aware.

Your second \ref is to an actual image, and is located correctly; slightly-edited code below, along with output and comments:

/proc/checkrefs()
var/type = /image
var/ref,foundpath,instance,newref,newfound
for(var/path in typesof(text2path("[type]")))
ref = "\ref[path]" // this is a reference to the TYPE /image, not an image!
foundpath = locate(ref)
if(foundpath)
world.log << "[ref] [path] found: [foundpath]"
else
world.log << "[ref] [path] not found!" // this prints, since types can't be locate()d
// [0x3f000005] /image not found!

instance = new path
newref = "\ref[instance]" // this one's a reference to an OBJECT of type /image
newfound = locate(newref)
if(newfound)
world.log << "[newref] [path] found: [newfound] ([newfound == instance])" // so this prints, since objects *can* be locate()d
// [0xd000001] /image found: (1)
else
world.log << "[newref] [path] not found!"
world.log << ""
For the most part, things with a \ref can be locate()ed including strings and other oddities.

var/blah = "blahblahblah"
world << "\ref[blah]"
world << "[locate("\ref[blah]")]"

that fact that's not working with types is technically speaking, odd.
GinjaNinja32 wrote:
This isn't a bug.

Yes, it is. All types paths are actually static objects that hold the information used to instantiate them.

Your first \ref is a reference to the type /image; types can't be locate()'d as far as I'm aware.

That's exactly the point. The ONLY types that can't be locate()d are those derived from /image! You would have known that if you actually tried running my code instead of assuming otherwise.

MrStonedOne wrote:
The fact that's not working with types is technically speaking, odd.
It does work with types; just not /image types.

I didn't want to just show the output here because it has been color coded to be easier to see, but since nobody believes me, here it is:
[0x3f000000] /image/myimage not found!
[0x3f000000] new /image/myimage was found ().
[0x3f000001] /image not found!
[0x3f000001] new /image was found ().
[0x20000002] /datum was found.
[0x20000002] new /datum was found (/datum).
[0x9000003] /atom/movable was found.
[0x9000003] new /atom/movable was found (the movable).
[0xa000004] /atom was found.
[0xa000004] cannot create new /atom!
[0x9000005] /obj was found.
[0x9000005] new /obj was found (the obj).
[0xa000006] /turf was found.
[0xa000006] cannot create new /turf!
[0xb000007] /area was found.
[0xb000007] new /area was found (the area).
[0x20000009] /sound was found.
[0x20000009] new /sound was found (/sound).
[0x2000000a] /icon was found.
[0x2000000a] new /icon was found (/icon).
[0x2000000b] /matrix was found.
[0x2000000b] new /matrix was found (/matrix).
[0x2000000c] /database/query was found.
[0x2000000c] new /database/query was found ().
[0x2000000d] /database was found.
[0x2000000d] new /database was found ().
[0x2000000e] /exception was found.
[0x2000000e] new /exception was found (/exception).
[0x2000000f] /regex was found.
[0x2000000f] cannot create new /regex!
[0x3f000010] /mutable_appearance not found!
[0x3f000010] new /mutable_appearance was found ().
[0x8000000] /mob was found.
[0x8000000] new /mob was found (the mob).

The code that I provided is a loop the provides everything. Please test it yourself to make sure you get the same results.
In response to Multiverse7
Multiverse7 wrote:
The code that I provided is a loop the provides everything.

The code that you provided did not make clear what it was meant to be run on/with, requiring the user to specify paths that you did not make clear what they should be; see below

proc/testpath(type)
var/found = locate("\ref[type]")
if(!found) world.log << "[type] -> *null*"
else if(found != type) world.log << "[type] -> [found] (!)"
else world.log << "[type] -> [found]"
try
var/x = new type
found = locate("\ref[x]")
if(!found) world.log << "[type] instance -> *null*"
else if(found != x) world.log << "[type] instance -> [found] (!)"
else world.log << "[type] instance -> [found]"
catch
world.log << "[type]: failed to create"

/world/New()
for(var/type in list(/datum, /atom, /obj, /mob, /image))
testpath(type)



/datum -> /datum
/datum instance -> /datum
/atom -> /atom
/atom: failed to create
/obj -> /obj
/obj instance -> The obj
/mob -> /mob
/mob instance -> The mob
/image -> *null*
/image instance ->


In this format, it's obvious what the problem is. In the format you gave in the OP, it's not.

edit: typesof(/datum) apparently returns all this; still, that wasn't clear given the format (why is it an argument to the verb if typesof(/datum) will just test everything anyway?)

double edit:
Multiverse7 wrote:
I didn't want to just show the output here because it has been color coded to be easier to see, but since nobody believes me, here it is:

Why does it *need* color coding? It should be easy to read without it, if formatted right.

Lummox should be able to merely glance at a bug report like this (read: non-graphical bug, with demo) and see exactly where the issue is, what circumstances it occurs in, and what happens when it occurs. You've put in the work to make a demo, don't make the people investigating run it just to understand the issue :P
In response to GinjaNinja32
Do I really have to spoon feed everything? The output that my code provides is complete and excellent.
In response to Multiverse7
Multiverse7 wrote:
Do I really have to spoon feed everything? The output that my code provides is complete and excellent.

It's hardly spoon feeding. You wrote a demo, wrote up a bug report. You already have the output, and you're trying to convey the information you have (ie the bug) to other people. The output is possibly the best way you have of doing that. Why not post it?
You are right. I should have posted it, but you should at least put more effort into investigating if you are going to respond to a bug report. It will just lead to more confusion otherwise.
Pretty sure you also cant use if(image) on an initialized image
I'll definitely look into this. I'm sure it's an oversight in the code somewhere, probably in TestRef().
TestRef() didn't include the PIMAGE_REF type even though it included all the other prototype types, so I'm sure that's the entire root of this problem.
Lummox JR resolved issue with message:
locate() couldn't look up /image and its derived types by reference.
Hm just for clarity's sake does that mean if(image) will now return true?
If the image is a valid object, shouldn't if(image) have returned true before?

This fix only addresses lookups via locate().
if(image) works on 510, at least, and I doubt it'd be broken by 511.
Well I'll try it out later and if I can reproduce anything going wrong I'll make sure to report back here.
While weird image behavior is the topic, I'll throw this in the mix: calling datum-derived procs on an image seems to do nothing.

datum
proc/dispose()

image
dispose()
world.log << "image disposed"

// insert functional code here...

// when the line below is reached, you would expect to see "image disposed" output the log.
// instead, you see nothing, as if this line does not exist.
some_image.dispose()
/image, like /list is a special type that cannot have user-defined procs that work properly.
If I were to change the dispose() under /image to dispose_image(), it would work fine. Unless I'm misunderstanding your meaning of "user-defined procs", I don't see how this is the case.
There may have been a change to things at some point to allow for proc definitions under /image (as the last time I checked it didn't work at all, but that was ages ago).

However, /image isn't derived from /datum, so I'm more surprised dispose() compiles than anything. It shouldn't be a defined proc.
Page: 1 2