Welcome to Keen Software House Forums! Log in or Sign up to interact with the KSH community.
  1. You are currently browsing our forum as a guest. Create your own forum account to access all forum functionality.

Behaviour of saved blocks (error handling)

Discussion in 'Programming (In-game)' started by Xarniia, Feb 7, 2017.

Thread Status:
This last post in this thread was made more than 31 days old.
  1. Xarniia Trainee Engineer

    Messages:
    6
    Already tried a bit, but there was no null reference exception or what I would expect. Maybe someone else knows more what happens with saved blocks (global / member variable), when they change (e.g. deleted, damaged etc.) ingame.

    In my case, a rotor is handled by the script, but even if I delete it, the script runs on. Also, access its properties. So is the underlying object forever in memory or did I just not wait enough?
     
  2. Malware Master Engineer

    Messages:
    9,601
    Your variables do not / can not be changed by the game. Remember, this is just ordinary C# and thus follows ordinary C# rules. Ergo you must deal with this yourself.
     
    Last edited: Feb 7, 2017
  3. Xarniia Trainee Engineer

    Messages:
    6
    Guess you misunderstood a bit, but also made me dig deeper in C#. Maybe my problem is also a bit related to a more hardware oriented view. My problem is a bit relating to this, because the game changes it’s object every frame, so also the variables (global variables IMyRotorStator) ‘change’.

    I already found out if an object gets null the interface it was created from stays like it was in ordinary C#. (This I haven’t found explained in any book I own.) So, that matches the answer. But does not imply this behaviour can be expected always. Just consider the MyRotor-Class (in the game engine) would do something special (e.g. throwing an exception), if an PB interface tries to access when already pending for deletion.

    But if it’s just ordinary C# behaviour, the script will not fail by exception, but by what it should do. In the example above this would mean not handling a deleted / destroyed rotor. The second aspect of making the code more reliable is therefor, knowing about changes of the ‘real world’. So, if I don’t want to scan the grid, is there a solution to find out if the object the interface was created of still exists – or however it’s handled in SE? Even if I know the answer will most likely be just no, because IsFunctional or IsWorking don’t change to false while the rotor (cube) is deleted. But at least it works, it the cube is destroyed / grinded. So, it’s a creative mode problem only.
     
  4. JulianB Trainee Engineer

    Messages:
    15
    Hmmm... I think it's more like this way: You have -for example - an object of a class that implements the interface IMyTerminalBlock and you change the properties of that object. When the block that this object refers to is destroyed in the game, the object itself won't be "deleted" since your variable still contains a reference to this object (garbage-collector stuff). So you have to check if the block is destroyed for yourself.
    My solution to this would be something like the following (but I have not tested it nor am I very familiar with all of this):
    Code:
    IMyTerminalBlock block;
    IMySlimBlock blockSlim;
    public void Main(string argument) {
        if (block == null) {
            block = GridTerminalSystem.GetBlockWithName("test");
            blockSlim = block?.CubeGrid.GetCubeBlock(block.Position);
        }
    
        if (blockSlim == null) {
            Echo("block does not exist");
        }
        else if (blockSlim.IsDestroyed) {
            Echo("block has been destroyed");
        }
        else {
            Echo("block exists");
        }
    }
     
  5. Phoera Senior Engineer

    Messages:
    1,713
    interface is not an instance, it just a subset of data/contract to real object.
    interface itself will never go null(only WeakReference can do this), same as object. but deleted object is often have removed it's internal data(data you don't see), and try to access it will give you NRE.
     
  6. mric Trainee Engineer

    Messages:
    27
    Xarniia I have the impression you have a misunderstanding about what SE scripting allows you to do.

    A script in a Programmable Block is a piece of code that is not linked inherently to your blocks.
    If you add or remove blocks in your grid the script will not know. Unless you code your script so that it checks all blocks each time it runs.

    Said differently.
    If your script runs a first time and get the list of blocks and store it in some variable (in script).
    Then next execution your script does not update the list, but you have deleted a block, then the block does not exist but your script still has a reference to the non existent object. Which is null.

    Therefore you must code your script to be resilient.
    Whether you test the variable is not null (which is basic good programming).
    Or at the begining of your main() you add some code to make sure you update your list of blocks you want to process.

    Did I answer your point or did I miss ?
     
  7. Malware Master Engineer

    Messages:
    9,601
    The game does not change its object every frame. The variables do not change unless you change them. There is no distinction between the interface and "the object the interface was created of". The interface represents the object itself as it's seen by the game. Unfortunately there's currently no way to determine if a block has been closed.

    I know it's ordinary C# behavior because it's just an ordinary C# compiler. I should know. I wrote it. The instruction counting etc. is injected into the source code ahead of compilation.
     
    • Agree Agree x 1
  8. hellokeith Apprentice Engineer

    Messages:
    335
  9. Xarniia Trainee Engineer

    Messages:
    6
    Thank you all very much for all the input! :)
    From here and the other thread and a bit of trying I think I found a bit of an answer and how to deal with it.

    In survival IsFunctional and IsWorking provide a good base for checking if a block still exists and further error handling. But as Malware pointed out, there is no way to check if the block has been closed. Unsatisfying, but good answer. ;)
    With the (in my opinion unexpected) behaviour in creative, that (right click) deleted blocks are still functional and working, guess an error handling just can’t handle everything at the moment. Unless one scans the grid regularly.
     
Thread Status:
This last post in this thread was made more than 31 days old.