This is a really elementary question, but I’ve never had to do this before mostly because I’ve never programmed a plugin before.
I have a plugin that makes use of a singleton UObject (let’s call it USingleton) that it needs to be able to distribute to a bunch of actor components. The actor components need to be using the same USingleton. But the problem is keeping the USingleton alive. I can’t put the USingleton in the plugin module object (that inherits from IModuleInterface) because that object isn’t a UObject and can’t have UPROPERTY’s and can’t keep the USingleton from being GC’d. And I need the actor components to be able to find the USingleton that already exists (or create one if it doesn’t exist). If this was a game, then the standard advice is “put it in the player controller” but I can’t do that in a plugin.
What do you think I should do here? There’s no smart pointer that the IModuleInterface module object could own that would keep the UObject from being GC’d is there? Something like TStrongObjectPtr<> rather than TWeakObjectPtr<>?
This is even possible considering that UObject creates a CDO?
Do you really need to use a singleton? There is a reason why this approach is considered bad in most cases. there is more cons than pros even in “pure” cpp.
“And I need the actor components to be able to find the USingleton that already exists (or create one if it doesn’t exist).”
can you just do that every time and forget about keeping it alive forever?
or IF it becomes a performance issue resolve it in the game that uses the plugin by spawning a basic actor that holds a reference to USingleton somewhere in the level
Lifetime-wise it might indeed not be the best idea to create the object inside your module, since the module will be initialized fairly early on.
This depends a bit on how you interact with your UObject and whether it should exist for the whole lifetime of your application. Subsystems might be an alternative, and your actors could directly access the subsystem, so you might even get away without using a UObject. This depends on what you’re using the singleton UObject for.
Regarding Garbage collection, there is a TStrongObjectPtr that does what you want, it will act as a reference to the object, even if it exists outside a UPROPERTY.
Another alternative might be using AddToRoot() and RemoveFromRoot() to prevent the object from being garbage-collected.
Well these are all fantastic solutions - and I’ve decided that I’m going to use a subsystem for this. Thanks everyone for answering! I’m going to mark UE_Seb.Tho’s answer as the solution because it’s the most comprehensive.