Add a builtin/core function which would return an invalid wirelink.
Currently this is only possible if "wiring" extension is enabled, like:
local NoWirelink = noentity():wirelink()
Duplicate that function, rename it, rip out everything and just make it return nil :)
I think you can already do this, like this:
local Array = array()
local NoWirelink = Array["InvalidKey",wirelink]
but that's a huge hack, so a real function would definitely be cleaner. What do you need this for, though? I've never needed a nowirelink function.
@Divran For example, in user-defined function which returns a wirelink, I want to be able to return an invalid wirelink.. Code example (from extended library in array_contains file (not pushed yet)):
function wirelink array:containsWirelink(Wirelink:wirelink)
{
foreach (Index, Value:wirelink = This)
{
if (Value == Wirelink)
{
return Wirelink
}
}
return ??? # nowirelink()
} # End of function xwl=r:containsWirelink(xwl)
you know, the reason E2 (or lua for that matter) doesn't have any "array contains" functions is because they are bad. Any time you do that, you should be using a lookup table.
@Divran The problem with that is, I don't know how could I possibly track a reference to an array. I would probably have to wrap array(...) function into a (class) library, which is sort of what I don't want to do..
So, I guess I can't do anything better than that (that I know of).. :(
In this case, since wirelinks can't be an index in a table, you would need to get the entity ID:
function wirelink array:containsWirelink( Wirelink:wirelink ) {
local EntityID = Wirelink:entity():id()
return This[EntityID,wirelink]
}
Notice that this function uses a lookup array. This is an array with non-sequential keys, which are only supposed to be used for lookup requests such as these. However, if necessary, you can also use foreach to iterate the lookup array.
Alternatively, you can use a table, but since the key here is always a number, arrays work too, and foreach loops don't work on the numerical keys of a table (you'd have to use the function that retrieves the tables indexes instead).
Next, you would need to redesign your array/table so that it's a lookup table instead of a list, or alternatively keep two: one list and one for lookups (if you still need the list for something).
Since E2 is limited in how much computations it can perform at any given time, having two arrays/tables with the same data is a small price to pay to be able to check if a value exists in an array/table of any size. In your "contains" function, if the array contains more than about 100 values, the E2 would crash. The code I posted above works even if your array contains so many values that Gmod runs out of memory (aka millions).
(Fun fact: If this was in Lua instead, we could've simply used a lookup table with the wirelink itself as the key, since Lua allows you to use literally anything as table keys.)
EDIT: all of this still doesn't entirely dismiss the idea of a nowirelink function.
Any cookie for me?
Oh, right... It is funny, how I forgot about the following being possible.
##ifdef entity:wirelink()
local DefaultWirelink = noentity():wirelink() # Note, requires "wiring" extension enabled.
##endif
function wirelink nowirelink()
{
#print("In xwl=nowirelink() function")
# Simply, by omitting a return statement I guess it returns nil to Lua (as invalid wirelink).
}
local NoWirelink = nowirelink()
print("IsValid: " + NoWirelink:entity():isValid()) # Prints "IsValid: 0"
local AreEqual = DefaultWirelink == NoWirelink
print("AreEqual: " + AreEqual) # Prints "AreEqual: 1"
No cookie..?
If #1095 is merged then you'll have to return a value, though you could recreate the effect with
function wirelink nowirelink()
{
return noentity():wirelink()
}
@bigdogmat
function wirelink nowirelink()
{
return noentity():wirelink()
}
Which requires a "wiring" extension enabled in the first place. _facepalm_. See my code above..
Edit:
I would suggest to merge #1140 before merging #1095. Here is a little insight why:
So, until the both are merged, stick with the following code:
#ifndef nowirelink()
function wirelink nowirelink()
{
}
#endif
Is just perfect. Because, once #1140 is merged then E2 will have xwl=nowirelink() function defined in core. That's when above code will automatically switch and won't define the function in E2 file anymore. And then #1095 can be merged without worrying about such things (breaking code, etc).
That's my little (backward) compatibility suggestion :hourglass_flowing_sand:
Ah, I see. Couldn't you just create a persisted wirelink then?
Edit: Eh, well that'd only be usable once so nvm