[No] Multiple extends

Moderator: GZDoom Developers

Multiple extends

Postby Rip and Tear » Tue Dec 25, 2018 11:49 pm

One of the limitations of ZScript's `extend` functionality is that it can only extend classes defined in the same mod. Unfortunately, this makes it significantly less useful when working with classes that share a superclass in gzdoom.pk3. Often, you will need to either include the same code in multiple places, or replicate code that already exists in gzdoom.pk3.

I believe this feature suggestion would help to somewhat alleviate that. Class extensions should be able to be used on multiple classes at once, separated with commas. This would just be a bit of syntactic sugar added to the compiler.

Code: Select allExpand view
extend class foo, bar {
    //...
}

would be exactly equivalent to

Code: Select allExpand view
extend class foo {
    //...
}
extend class bar {
    //...
}

This would help to reduce code duplication when inheriting from actor classes in gzdoom.pk3. For example, if you were to define custom classes inheriting from Hexen's three playable classes, you could then add behavior to all three of them without having to copy/paste code.
User avatar
Rip and Tear
King of creative usernames
 
Joined: 02 May 2017
Operating System: Mac OS X 10.8 or later
Graphics Processor: Intel (Modern GZDoom)

Re: Multiple extends

Postby Graf Zahl » Wed Dec 26, 2018 2:06 am

I don't think this is a good idea. It would give modders a wrong impression of having behavior in different classes that can be accessed through a common interface. Even if this was implemented you'd still have two unrelated classes that may have copies of the same implementation but absolutely no means to access this in a common fashion.

Besides, since it still would be limited to classes in the same translation unit, it'd be better to code the common behavior properly into a base class where it is properly shared.
In short, all it'd do is allow for dirty implementations.
User avatar
Graf Zahl
Lead GZDoom Developer
Lead GZDoom Developer
 
Joined: 19 Jul 2003
Location: Germany

Re: Multiple extends

Postby Rip and Tear » Wed Dec 26, 2018 10:17 am

Graf Zahl wrote:Besides, since it still would be limited to classes in the same translation unit, it'd be better to code the common behavior properly into a base class where it is properly shared.

Though this would still require you to replicate code that already exists in gzdoom.pk3. Sticking with the Hexen class example, you would need to make make a class which inherits from PlayerPawn to include common behavior, then copy/paste the entire definitions for all three classes and inherit from the custom class.

The only other option I've come across is to make a helper class with static methods and pass `self` as the first argument. Which works, but is also very clunky.
Last edited by Rip and Tear on Wed Dec 26, 2018 9:02 pm, edited 2 times in total.
User avatar
Rip and Tear
King of creative usernames
 
Joined: 02 May 2017
Operating System: Mac OS X 10.8 or later
Graphics Processor: Intel (Modern GZDoom)

Re: Multiple extends

Postby Graf Zahl » Wed Dec 26, 2018 10:39 am

Can you please lay out your use case? I somehow have a feeling that you are approaching this from the wrong angle conceptually.
User avatar
Graf Zahl
Lead GZDoom Developer
Lead GZDoom Developer
 
Joined: 19 Jul 2003
Location: Germany

Re: Multiple extends

Postby Rip and Tear » Wed Dec 26, 2018 6:41 pm

Graf Zahl wrote:Can you please lay out your use case? I somehow have a feeling that you are approaching this from the wrong angle conceptually.

Say someone wrote improved versions of the monster 'AI' functions (such as A_Chase) and I wanted to implement it into my Doom mod. Ideally, the per-actor implementation would just be

Code: Select allExpand view
class NewZombieMan : ZombieMan replaces ZombieMan {
    States {
    See:
        POSS AABBCCDD 4 A_EnhancedChase();
        Loop;
    }
}

In actuality, I would need to either copy and paste the functions into each actor definition; include the actor functions in a base monster class to inherit from, thereby losing the ability to inherit from the monster classes already defined in gzdoom.pk3; or use the clunky helper class method I described.

Perhaps this diagram will help to explain the problem.

Diagram.png
User avatar
Rip and Tear
King of creative usernames
 
Joined: 02 May 2017
Operating System: Mac OS X 10.8 or later
Graphics Processor: Intel (Modern GZDoom)

Re: Multiple extends

Postby Caligari87 » Wed Dec 26, 2018 8:48 pm

One potential workaround is to use a static function in a separate thinker/class as a proxy. Matt does this in Hideous Destructor, for example.
Code: Select allExpand view
class NewZombieMan : ZombieMan replaces ZombieMan {
    States {
    See:
        POSS AABBCCDD 4 MyFunctions.EnhancedChase(self);
        Loop;
    }
}

class MyFunctions {
    static void EnhancedChase(actor caller) {
        //do fancy movement
        caller.vel.x += 15;
    }
}

8-)
User avatar
Caligari87
I'm just here for the community
User Accounts Assistant
 
Joined: 26 Feb 2004
Location: Salt Lake City, Utah, USA
Discord: Caligari87#3089

Re: Multiple extends

Postby Graf Zahl » Thu Dec 27, 2018 2:36 am

To get here it is first necessary to scriptify all actor subclasses. Unfortunately there's still two major ones which aren't scriptable yet, namely PlayerPawn and DynamicLight, the former because it still depends on too much native functionality and the latter one because it is normally the one with the highest cumulative thinker overhead of all classes in a loaded map. To scriptify this one I first have to uncouple the light rendering from the backing actor and thanks to people hacking its properties live (since the args are modifiable even from ACS) this is not going to be easy without breaking stuff.
User avatar
Graf Zahl
Lead GZDoom Developer
Lead GZDoom Developer
 
Joined: 19 Jul 2003
Location: Germany

Re: Multiple extends

Postby Rip and Tear » Thu Jan 03, 2019 10:18 am

Caligari87 wrote:One potential workaround is to use a static function in a separate thinker/class as a proxy. Matt does this in Hideous Destructor, for example.
Code: Select allExpand view
class NewZombieMan : ZombieMan replaces ZombieMan {
    States {
    See:
        POSS AABBCCDD 4 MyFunctions.EnhancedChase(self);
        Loop;
    }
}

class MyFunctions {
    static void EnhancedChase(actor caller) {
        //do fancy movement
        caller.vel.x += 15;
    }
}

8-)

I'm aware of this method and it's definitely the best one available at the time. But having to prefix with `caller` so often leads to rather clunky syntax.
User avatar
Rip and Tear
King of creative usernames
 
Joined: 02 May 2017
Operating System: Mac OS X 10.8 or later
Graphics Processor: Intel (Modern GZDoom)

Re: Multiple extends

Postby Graf Zahl » Thu Jan 03, 2019 10:40 am

I'm working on it. I'm almost done exporting PlayerPawn which is the last remaining blocker for allowing user-side extends of class Actor.
User avatar
Graf Zahl
Lead GZDoom Developer
Lead GZDoom Developer
 
Joined: 19 Jul 2003
Location: Germany

Re: Multiple extends

Postby Caligari87 » Thu Jan 03, 2019 10:54 am

excited incoherent screaming

Graf you're the best. This'll be a game-changer.

8-)
User avatar
Caligari87
I'm just here for the community
User Accounts Assistant
 
Joined: 26 Feb 2004
Location: Salt Lake City, Utah, USA
Discord: Caligari87#3089

Re: Multiple extends

Postby Major Cooke » Thu Jan 03, 2019 11:18 am

How will this work when done?
User avatar
Major Cooke
Do unto others as you would have unto you. Judge yourself first.
 
Joined: 28 Jan 2007

Re: Multiple extends

Postby Graf Zahl » Thu Jan 03, 2019 12:03 pm

It means that 'extends' blocks to all actor classes can be done in user code. The reason why this wasn't possible yet is that all the native children would have broken if a base class was extended.

For non-actors this isn't really important because there's little to be gained by extending them.
User avatar
Graf Zahl
Lead GZDoom Developer
Lead GZDoom Developer
 
Joined: 19 Jul 2003
Location: Germany

Re: Multiple extends

Postby Rip and Tear » Thu Jan 03, 2019 12:30 pm

heavy breathing
User avatar
Rip and Tear
King of creative usernames
 
Joined: 02 May 2017
Operating System: Mac OS X 10.8 or later
Graphics Processor: Intel (Modern GZDoom)

Re: Multiple extends

Postby Major Cooke » Thu Jan 03, 2019 12:43 pm

This sounds like it's eventually paving the way towards being able to inject/override states without needing to replace the actor. Removing the need to replace one actor with another just so it doesn't have to be given some little tweaks would be a godsend.

For example, if an addon modifies a state, it could TRULY replace it -- possibly even affecting the goto -- via some definition like:
Code: Select allExpand view
extends class Zombieman
{
States.MyAddonIdentifierHere
{
Spawn:


...which would be in the addon code, replacing the spawn state without replacing the actor. But the actor themselves could still use something like Goto <ClassName>::Spawn or something to make it use the original.

But then again I am effectively deluding myself into thinking its even possible. Feel free to correct me if I'm not deluding though!
User avatar
Major Cooke
Do unto others as you would have unto you. Judge yourself first.
 
Joined: 28 Jan 2007

Re: Multiple extends

Postby Graf Zahl » Thu Jan 03, 2019 1:04 pm

State label overrides won't be possible. That'd be too volatile.
User avatar
Graf Zahl
Lead GZDoom Developer
Lead GZDoom Developer
 
Joined: 19 Jul 2003
Location: Germany

Next

Return to Closed Feature Suggestions

Who is online

Users browsing this forum: No registered users and 0 guests