what is the difference

Discussions about Coding and Scripting
User avatar
Rakiayn
Masterful
Posts: 550
Joined: Fri Aug 28, 2009 3:33 pm

what is the difference

Post by Rakiayn » Mon Mar 08, 2010 7:39 pm

between

Code: Select all

If ((other.isa('something'))
{
...
}
and

Code: Select all

if (something(other) != none)
{

}

Darkness
Experienced
Posts: 81
Joined: Mon Mar 01, 2010 10:12 pm
Location: Brazil

Re: what is the difference

Post by Darkness » Mon Mar 08, 2010 8:24 pm

I believe something(other) might return accessed nones.

Usually you do a check with .IsA, and then, if you wanna run specific functions on it, you may name it locally. Example:

Code: Select all

function something()
{
	local pawn p;

	if ( owner != none && owner.IsA('Pawn') ) // check if it's a pawn, since owner can be any actor
	{
		p = pawn(owner);
		p.health = 100;
		p.groundspeed = 500;
		...
	}
}
At least that's how I use them, based on observation. If I do something like pawn(owner).health = 100, without checking if only owners that are pawn, it would return an accessed none, in case it wasn't a pawn.

But of course you could use pawn(owner).health = 100 if it's a place where you ALWAYS know that:
a - there would ALWAYS be an owner;
b - owner would ALWAYS be a pawn.

I also tend to name things locally, even if I know there'll always be a specific type to run the function, to make it shorter and more organized, but usually it's only worth when you're going to use plenty lines with the same actor, in his more specific class (e.g playerpawn).
Last edited by Darkness on Mon Mar 08, 2010 8:32 pm, edited 2 times in total.

User avatar
Shadow
Masterful
Posts: 725
Joined: Tue Jan 29, 2008 12:00 am
Personal rank: Mad Carpenter
Location: Halle/Leipzig, Germany

Re: what is the difference

Post by Shadow » Mon Mar 08, 2010 8:28 pm

The first one checks if an entity of that class with that class name exists (also affecting referenced subclasses)

The second is a (meta)typecast from a parent class to a subclass, if the entity/reference of the parent class is known, it returns the cast type, though one does not always know if that reference to the entity exists one first checks with the NOT (!=) operator that there's no NULL reference, which would lead to the infamous accessed nones.
Image

User avatar
Feralidragon
Godlike
Posts: 5300
Joined: Wed Feb 27, 2008 6:24 pm
Personal rank: Work In Progress
Location: Liandri

Re: what is the difference

Post by Feralidragon » Mon Mar 08, 2010 9:23 pm

Also:

Code: Select all

other.isa('something')
Works between different packages, without the need of compile them all or add them to the EditPackages list.

While:

Code: Select all

something(other)
Only works if the Class something exists in your package or in another package above in EditPackages.

So depending on the situation, it might be better to use one or another, since the first is independent but is suitable to typing errors which will compile correctly, but the code might not work in the game and then you take ages just to find you mistyped the class name, and the second is dependent from a really existing class in your package or another package, and it won't work if it doesn't exists, but if you mistype it, it will stop the compilation and give an error there, and you will be able to correct it right away.

User avatar
Rakiayn
Masterful
Posts: 550
Joined: Fri Aug 28, 2009 3:33 pm

Re: what is the difference

Post by Rakiayn » Mon Mar 08, 2010 11:46 pm

ok thanx!
I usually use the second . but I think I will use the first one more often. being able to refer to ther packages with the game really needing to have it is a very nice

User avatar
Barbie
Godlike
Posts: 2069
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: what is the difference

Post by Barbie » Tue Dec 22, 2020 12:47 am

Old thread but still facts in fog:
Do

Code: Select all

SomeActor.IsA('WhatEverClass')
results in the same as

Code: Select all

String(SomeActor.Class.name) ~= "WhatEverClass"
?
While on the other hand such as

Code: Select all

SomeActor(OtherActor) != None
ClassIsChildOf(class TestClass, class ParentClass)
do a binary compare in the object tree?
"Multiple exclamation marks," he went on, shaking his head, "are a sure sign of a diseased mind." --Terry Pratchett

Buggie
Adept
Posts: 420
Joined: Sat Mar 21, 2020 5:32 am

Re: what is the difference

Post by Buggie » Tue Dec 22, 2020 1:23 am

1. No. It check all parents names too. Not just this class name.
2. "SomeActor" will be expanded by linker on compile time.
Same with classes send as params to ClassIsChildOf.
So there you operate were specific classes and similar names not work.

User avatar
sektor2111
Godlike
Posts: 5209
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: what is the difference

Post by sektor2111 » Tue Dec 22, 2020 7:44 am

My two cents around - looking at post from 2010

Code: Select all

if (....Owner.Isa('Pawn'))
it's more like wreck and it slows down all time - you can use a Bool first, before testing what sort of pawn is that or else you'll test everything if it's desired Pawn.

Code: Select all

if (....Owner.bIsPawn) //Prevent Non-Pawns from being checked and it takes almost nothing in CPU timer
{
	//Do the rest of checks
}
Last time when I did some clocking execution on my rig it took 0.000000 seconds to check a boolean while ISA was longer.

As for ISA('Pawn') and Pawn(Other) != None I got the same results because I USED Both cases - ISA to me was a tiny bit slower...

UnType.h

Code: Select all

//
// See if this object belongs to the specified class.
//
inline UBOOL UObject::IsA( class UClass* SomeBase ) const
{
	guardSlow(UObject::IsA);
	for( UClass* TempClass=Class; TempClass; TempClass=(UClass*)TempClass->SuperField )
		if( TempClass==SomeBase )
			return 1;
	return SomeBase==NULL;
	unguardobjSlow;
}

Buggie
Adept
Posts: 420
Joined: Sat Mar 21, 2020 5:32 am

Re: what is the difference

Post by Buggie » Tue Dec 22, 2020 11:24 am

this is c++. So by code you never know what happen here because each operator can be overloaded with any fancy stuff.
In general, I have to admit that I’m a little bit scared of language features that hide things. When you see the code

Code: Select all

    i = j * 5;
… in C you know, at least, that j is being multiplied by five and the results stored in i.

But if you see that same snippet of code in C++, you don’t know anything. Nothing. The only way to know what’s really happening in C++ is to find out what types i and j are, something which might be declared somewhere altogether else. That’s because j might be of a type that has operator* overloaded and it does something terribly witty when you try to multiply it. And i might be of a type that has operator= overloaded, and the types might not be compatible so an automatic type coercion function might end up being called. And the only way to find out is not only to check the type of the variables, but to find the code that implements that type, and God help you if there’s inheritance somewhere, because now you have to traipse all the way up the class hierarchy all by yourself trying to find where that code really is, and if there’s polymorphism somewhere, you’re really in trouble because it’s not enough to know what type i and j are declared, you have to know what type they are right now, which might involve inspecting an arbitrary amount of code and you can never really be sure if you’ve looked everywhere thanks to the halting problem (phew!).

When you see i=j*5 in C++ you are really on your own, bubby, and that, in my mind, reduces the ability to detect possible problems just by looking at code.

None of this was supposed to matter, of course. When you do clever-schoolboy things like override operator*, this is meant to be to help you provide a nice waterproof abstraction. Golly, j is a Unicode String type, and multiplying a Unicode String by an integer is obviously a good abstraction for converting Traditional Chinese to Standard Chinese, right?
https://www.joelonsoftware.com/2005/05/ ... ook-wrong/

In this concrete code:

Code: Select all

if( TempClass==SomeBase )
You not know what happen here. Look like operator overloaded and classes equals when has same names. Possible exists another checks. IDK.

Code: Select all

TempClass=(UClass*)TempClass->SuperField
What about this? This too all transparent?