[ZScript] DECORATE custominventories partly broken

Forum rules
Please don't bump threads here if you have a problem - it will often be forgotten about if you do. Instead, make a new thread here.

Post a reply

Smilies
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :geek: :ugeek: :!: :?: :idea: :arrow: :| :mrgreen: :3: :wub: >:( :blergh:
View more smilies

BBCode is OFF
Smilies are ON

Topic review
   

Expand view Topic review: [ZScript] DECORATE custominventories partly broken

Re: [ZScript] DECORATE custominventories partly broken

by Graf Zahl » Sun Nov 13, 2016 12:45 pm

No, I just forgot to push it.

Re: [ZScript] DECORATE custominventories partly broken

by Major Cooke » Sun Nov 13, 2016 11:58 am

I see. I take it the fix is being withheld for now to address that at the same time?

Re: [ZScript] DECORATE custominventories partly broken

by Graf Zahl » Sun Nov 13, 2016 10:12 am

Major Cooke wrote:
Graf Zahl wrote:The really annoying thing here is that much of the problems could have been avoided, had someone thought of it when DECORATE got its anonymous functions.
Okay, I just wanted to clarify... Is this a problem with calling A_SetUserVar itself, direct assignment or both? If it's just A_SetUserVar, then I wouldn't really have any problem changing it.
It has nothing to do with A_SetUserVar. The thing is that the DECORATE anonymous function support was happily slapped together without ever thinking about implementation details long term ramifications. And people went on using this stuff. So here we are, almost a year later and finally we see how deeply these problems are infesting the foundations of the entire system, so deep in fact that no patching over will make ZScript clean. It has to be aware of DECORATE quirks and cannot do a clean but incompatible implementation of these things.

And as I just saw in a new report, there seem to be worse problems lurking.

Re: [ZScript] DECORATE custominventories partly broken

by Major Cooke » Sun Nov 13, 2016 10:06 am

Graf Zahl wrote:The really annoying thing here is that much of the problems could have been avoided, had someone thought of it when DECORATE got its anonymous functions.
Okay, I just wanted to clarify... Is this a problem with calling A_SetUserVar itself, direct assignment or both? If it's just A_SetUserVar, then I wouldn't really have any problem changing it.

And can direct assignment be used in custom inventory actors once they are owned? Like:

Code: Select all

if (CheckClass("SpecialZombie"))
{
    myZombieVar = 2; //Assuming SpecialZombie has it already
}
And can this be done without needing to declare an actor cast, since there's no 'self' pointer (at least I think)?

Re: [ZScript] DECORATE custominventories partly broken

by Major Cooke » Sun Nov 13, 2016 8:33 am

Graf Zahl wrote:documented in a sane fashion
I'm still reading through all the posts but this caught my attention. Would you be willing to update this since I'm still a little lost? In regards to what's going on here. Also not seeing the fix yet.

Re: [ZScript] DECORATE custominventories partly broken

by Graf Zahl » Sun Nov 13, 2016 7:55 am

Now I am satisfied with the fix. It required quite a bit of changes to plug all the holes. Here's a summary:

1. Applied Leonard's fix to properly resolve identifiers.
2. Mark any action function that contains variable access as 'unsafe'.
3. Run a check over all states at the end to see if any of the reserved labels for weapons or CustomInventorys reaches an unsafe state via its state link chain. If so, print an error and increment the error counter so that any such occurence will terminate the setup process. While this may break some mods, these are clearly broken to begin with so this is no concern.
4. Make sure that StateProviders can only call functions which have a self pointer of type Actor, they will error out if some code tries to call something else directly from a state. This required changing all weapon-based actions to get the 'action' keyword.

Needless to say, it's still a mess, but how can we solve this... :?
I think splitting the state block into injectable and non-injectable states will be unavoidable. The rule would be that injectable states require an action function with a self pointer of type 'Actor' and that it is not allowed to mix them (which is easy to test, there's only 3 places in the entire code where this needs to be done.)
The main problem would be DECORATE then. My approach would be to make all DECORATE states non-injectable, except those coming from a StateProvider which can be used as both. If we can make such a clear separation I think the big problems will go away (except for DECORATE state providers, of course) and it can all be documented in a sane fashion, especially what the 'action' keyword is actually doing - which still may require some changes.

Re: [ZScript] DECORATE custominventories partly broken

by Graf Zahl » Sun Nov 13, 2016 6:15 am

Graf Zahl wrote: About swapping the pointers, the problem is not the anonymous or even named functions, for those I fully agree that it can be done like that and if that was all there is I'd have done it like that.

Where I see problems is with direct function invocation on a state, which would basically be broken beyond repair as a feature. How should:

Code: Select all

class w : weapon
{
    states
    {
    ready:
        A_WeaponReady;
        loop
    }
}


be handled then, especially if this is trying to reference member variables? Should this just imply 'caller.' and if so, from what context should it resolve expressions?
And of course there's still the fact that DECORATE works the other way around so the entire code generation process has to be aware of this to avoid further problems.
Although I still think that this will cause more problems than it solves, let's do some brainstorming here. We should at least think it through once before making a decision that cannot be reversed later. The really annoying thing here is that much of the problems could have been avoided, had someone thought of it when DECORATE got its anonymous functions. I don't want to let this happen again.

If this gets done, what do we need to look out for?

First problem: Direct action function invocations are going to be a major problem then, because if self is the weapon/item, they will operate on this. But since weapons/items can call nearly anything Actor defines such invocations won't do what the user would expect, because the called function would receive the wrong self pointer.
For all direct weapon functions they could be rewritten to allow operating on the weapon as 'self', but then we'd have functions that can be used this way and others that can not. How do we explain this to users who come from DECORATE where this distinction is not being made? It's really complicating the use.

What does the code generator need to handle DECORATE with its inverted conditions? Is it enough to reverse the pointers or is more work needed? What I am thinking about is that some code assumes self to always be the a0 register.

Re: [ZScript] DECORATE custominventories partly broken

by Graf Zahl » Sun Nov 13, 2016 4:38 am

I've been working on a solution myself for the last half day, so I won't need another one.
About swapping the pointers, the problem is not the anonymous or even named functions, for those I fully agree that it can be done like that and if that was all there is I'd have done it like that.

Where I see problems is with direct function invocation on a state, which would basically be broken beyond repair as a feature. How should:

Code: Select all

class w : weapon
{
    states
    {
    ready:
        A_WeaponReady;
        loop
    }
}


be handled then, especially if this is trying to reference member variables? Should this just imply 'caller.' and if so, from what context should it resolve expressions?
And of course there's still the fact that DECORATE works the other way around so the entire code generation process has to be aware of this to avoid further problems.

EDIT: I had a closer look at your code. I think I'll mix it with my own runtime checks which simply flag the function itself as unsafe instead of injecting test code into the self dereferencing. That way I can outright print a warning when the function is about to be called and remove the function from the state. I think that is better than a runtime exception that gives little to no info what is wrong. It also allows to do some simple postprocessing checks to weed out problems that are trivially traceable to a special state label.

Re: [ZScript] DECORATE custominventories partly broken

by Leonard2 » Sun Nov 13, 2016 3:50 am

Graf Zahl wrote:Drawback: Syntax of weapon action functions will be completely messed up, not intuitive for modders
I still strongly disagree with that.
Here's an example based on a recent bug report:
Spoiler:
I would say that the second syntax would be much more intuitive and on top of that consistent with everything else within zscript.
Currently the best part is that it's even inconsistent across the class definition itself:

Code: Select all

Class NewPistol : Pistol
{
	int testing;
	States
	{
		Select:
			TNT1 A 0
			{
				invoker.testing = 9;
			}
			Goto Super::Select;
		Fire:
			TNT1 A 0
			{
				A_ChangeVelocity(0, 0, invoker.GetMyTest());
				A_LogInt(invoker.GetMyTest());
				A_LogInt(GetMyTest()); // This is broken by the way
			}
			Goto Super::Fire;
	}
	int GetMyTest() // non-action
	{
		return testing; // not invoker.testing???
	}
}
Graf Zahl wrote:Which may be necessary anyway if HUD overlays from arbitrary actors become a thing.
No no no you got it wrong, it's not overlays from arbitrary actors, it's overlays on arbitrary actors.
The current implementation limits their use to player actors only and my pull request aimed at removing said limitation.
Meaning that:
Graf Zahl wrote:Is it possible that if actor A defines some states, it can inject them into actor B's overlays
Is wrong unless of course it's a StateProvider like currently for players.
Graf Zahl wrote:Of course that will again open up the old problem of having to add a runtime check for DECORATE based states in StateProvider-derived classes because then the incorrect use cannot be detected at compile time.
Before I made assignment operators for decorate people were forced to use the A_SetUserVar function which is slower than doing a pointer check so I guess it can't be that bad.


Here's a pull request.
I think it's the best solution as it doesn't remove/change anything and fixes the issue.

Re: [ZScript] DECORATE custominventories partly broken

by Graf Zahl » Sun Nov 13, 2016 2:40 am

Yes, but not retroactively for existing mods. What you suggest already works.
The problem here is not the new stuff. For ZScript I'm not going to change anything, but we need to find a working solution for existing DECORATE mods.

Re: [ZScript] DECORATE custominventories partly broken

by Gez » Sun Nov 13, 2016 2:37 am

Would it be possible to use a pointer prefix to disambiguate user variables? invoker.user_scale vs. owner.user_scale?

Re: [ZScript] DECORATE custominventories partly broken

by Graf Zahl » Sun Nov 13, 2016 2:27 am

The thing with Leonard's code is simply that I do not know one thing: Is it possible that if actor A defines some states, it can inject them into actor B's overlays or only into its own? If only into its own, it'd be no problem. Then again, with a function like SetState available, you can basically do anything you want with states but I'd consider that user's risk.

Re: [ZScript] DECORATE custominventories partly broken

by Major Cooke » Sat Nov 12, 2016 8:28 pm

I wouldn't have a problem moving these things over to zscript if local arrays come in. Some of the other custominventories use very heavily nested arrays with for loops that shift array indices. Some of those arrays are fucking monstrous and would bloat the code by... I'd say about 20 times? Maybe more?
Graf Zahl wrote:If all else fails I go back to the beginning and implement different state blocks in ZScript for actors, weapons and items and you'll have to adjust all ZScript code that has already been written. Which may be necessary anyway if HUD overlays from arbitrary actors become a thing.
Perhaps Leonard aught to update his PR then, to ensure this won't cause issues. It is quite out of date after all, wouldn't hurt to get that going again.

Re: [ZScript] DECORATE custominventories partly broken

by Graf Zahl » Sat Nov 12, 2016 6:19 pm

That's precisely what my current favorite would be. Of course that will again open up the old problem of having to add a runtime check for DECORATE based states in StateProvider-derived classes because then the incorrect use cannot be detected at compile time.

Re: [ZScript] DECORATE custominventories partly broken

by Fishytza » Sat Nov 12, 2016 6:02 pm

I'm not sure if the parser can do this but. How about only apply the self parameter restriction if and only if NOT parsing from DECORATE AND the class is a StateProvider. Or would that cause other problems?

Top