Tessalator Posted May 24, 2021 Share Posted May 24, 2021 Background: I found that a world is available as soon as the engine starts static void Main(string[] args) { Engine.Init(args); var systemsRoot = new NodeDummy { Name = "SystemsRoot" }; World.SetRootNodeIndex(systemsRoot, 0); systemsRoot.AddComponent<User>(); var n = World.GetNodeByName("SystemsRoot"); var c = n.GetComponent<User>(); Debug.WriteLine(c.SystemConfig); ... } I ran the in different constructor/init processes and logged the results. I added two [MethodUpdate] with order -1 (Pre) and 1 (Post) (I hadn't realized that World runs after user code.) I'm writing some low-level systems (e.g., input and message bus). The docs indicate AppSystem is a good place for things like input systems. For reasons, I have code like the first three in the AppSystem constructor. Things mostly work fine... Problem: Except, I get an error on shutdown: "Unigine's object has been destroyed but you are trying to access it." The error occurs in every case except World Init (Which kind of makes sense since I'm working in World). Question: I understand why errors like this occur, but I'm not sure what to do about it in this case. I've been ignoring it, but it's time to find out more. I don't want to put these things in World Init because I want to use them to drive things in system and world init. Is there something I do to avoid/suppress this? If not, kind of hoping this is a bug because startup and shutdown aren't symmetrical. :) What is the risk if ignoring it if all else fails? Link to comment
alexander Posted May 25, 2021 Share Posted May 25, 2021 Hi Tessalator, Can you provide a small sample (project) of this problem? Because I don't understand where and why this error occurs. Best regards, Alexander Link to comment
Tessalator Posted May 25, 2021 Author Share Posted May 25, 2021 (edited) Hi alexander, I've attached the project I used to generate the table. The error can be produced by attaching a component to a node any time before World Init. // User.cs public class User : Component { ... } // In Main, System/World Constructor or System Init var systemsRoot = new NodeDummy { Name = "Systems Root" }; World.SetRootNodeIndex(systemsRoot, 0); systemsRoot.AddComponent<User>(); // Produces error on shutdown Error: ERROR: Unigine.Wrapper+NativeNullReferenceException: Unigine's object has been destroyed but you are trying to access it. Use IsValidPtr() method to check it. ERROR: at Unigine.Wrapper.ExceptionNullPointer() ERROR: at Unigine.Node.Node_getLifetime(HandleRef self) ERROR: at Unigine.Node.InternalGetLifetime() ERROR: at Unigine.Node.get_Lifetime() ERROR: at Unigine.ComponentSystem.Shutdown() ERROR: at Unigine.ComponentSystem.CSWorldLogic.Shutdown() ERROR: at Unigine.WorldLogic.CallShutdown() Edit Addition: On a related note, the reason I'm attaching the component is to register the component to access the "scheduler" (have Update called). I think you said you can manually register components in C++. Can you do that in C#? inputsystemtest.zip Edited May 25, 2021 by Tessalator Link to comment
alexander Posted May 25, 2021 Share Posted May 25, 2021 What if try to change the lifetime of this node? Does it help? // ... var systemsRoot = new NodeDummy { Name = "Systems Root" }; systemsRoot.Lifetime = Node.LIFETIME.ENGINE; // add this line World.SetRootNodeIndex(systemsRoot, 0); // ... Link to comment
Tessalator Posted May 25, 2021 Author Share Posted May 25, 2021 Nice! That does it. Looks like I need to study node lifecycles. Thanks. Link to comment
Recommended Posts