Load object into another class's List XNA C# - xna

Say you have a ScreenManager which inherits DrawableGameComponent, and a GamePlayScreen which inherits GameScreen. And GamePlayScreen is drawn through ScreenManagers ContentManager, and functions just like Game1.cs would. And its LoadContent looks like:
public override void LoadContent()
if (content == null)
content = new ContentManager(ScreenManager.Game.Services, "Content")
foreach (Objects object in objects)
object.LoadContent();
And object class calls same LoadContent method, but of course says object = content.Load<Texture2D>(" - ");... I'm getting the error:
"content = new ContentManager(ScreenManager.Game.Services, "Content") - Object reference not set to an instance of an object." In my objects class LoadContent method.
Is there a way to call GamePlayScreen's content or ContentManager, from the object class?
+++++++++++++++++++++++
Ok, I've realized what exactly the problem is. I'm using the Logic of the GameStateManagement Sample, "created by the head tech of Xbox Indie Games", which is in its own right is brilliant code... If all you're doing is making a main menu... lol...
BUT, ScreenManager is the DrawableGameComponent, its list of GameScreen's makes it and said screen the only functioning things in the Game. Or possibly only the screens are, and when they transition off ScreenManager is called, wakes up, adds new screen and goes to sleep again.
Thus NOT allowing you to call any classes, object list's, or anything contained in another class...
Now one may think, just create a new ScreenManager2 : DrawableGameComponent , or maybe even an ObjectManager : DrawableGameComponent .... Ahh ahhh, already beat you to it friend.....
Creating a new ObjectManager allows your objects to be drawn over everything your original ScreenManager deals with... True;... including your PauseScreen, and PauseMenu.... Garbage!
And before you mention a ScreenManager2, that to handle PauseScreen and PauseMenu, tried that as well. I successfully manipulated all code to do so, up until Play was selected for ScreenManager to tell LoadingScreen to function, then call GamePlayScreen...
Which leads to Asik being right, my content is Null, because I cannot figure out a way for my object class/classes to be called and Initialized with the way this code works.
Which leads to me asking the question correctly...
How do you call a class to Initialize, just long enough to allow LoadContent in the GamePlayScreen to gather said classes/objects information, to be put in its object list?
Lehman's terms: "GamePlayScreen on your LoadContent function, wake up Object1.cs, add object information in your ObjectList, tell Object1.cs to sleep, GamePlayScreen go on with your bad self..." ???

You are making use of GameComponent and DrawableGameComponent. Your subclasses that inherit from these have access to the Game instance via their GameComponent.Game property (that is, if you've passed it into their constructors rather than specifying null.
This is good. Just use GameComponent.Game.Content to access the ContentManager in each.

"Object reference not set to an instance of an object" is a NullReferenceException: it means you're trying to access something from a variable that is currently null. On the line you have posted, I see two possibilities: either ScreenManager.Game is null, or ScreenManager.Game.Services is null. Why? Because you're not initializing them by the time this line gets called.
That said, why not just pass the ContentManager that whatever class needs it rather than instantiate new ones?

With the complexity of ScreenManager, I found no way to load the content directly from the Object1 class, I was however able to call an older form of object handling:
In Object1 class...
Texture2D image;
public Object1(Texture2D texture)
{
this.image = texture;
//other information...
}
Even though SpriteBatch was never declared in the objects class, I was able to call:
public override void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(image, Rectangle, Color.White);
}
And in GamePlayScreen's LoadContent:
Texture2D tempImage = content.Load...
objectList.Add(new Object1(tempImage));
And then in GamePlayScreen's Draw function which calls for GameTime, I called:
foreach (Objects object in objectList)
object.Draw(spriteBatch);
After 2 weeks later, this is finally resolved... And I quote myself:
"It all looks so easy, until you're the one who needs to figure it out..."

Related

Swift - How to find all instances of a class, and all references that point to the same instance?

I inherited an application where certain class is instantiated and passed back and forth multiple times. So I have about 20 private and public variables where
Class instantiates: myClass = MyClass()
MyClass instance is passed back and forth: self.myClass = someOtherClass.myClass
Sometimes variable is passed from class to class multiple times
And a class may create a new instance or receive an instance from some other class in various cases
I want to fix this. But before changing anything I want to understand how many instances of that class I have, and which references point to the same instance.
What I do now: I am running the following statement in each method of MyClass:
print(Unmanaged.passUnretained(self).toOpaque())
and then additional prints in callers to identify who called that instance. This is quite tedious, but moreover it completely depends on my ability to cover all possible cases if this class usage at runtime, and it won't find nil references that classes may pass to each other (and which I need to know of)
So is there a better way? Or can this method be improved in some way?
Thanks in advance.
Sounds simple but why not add a static variable to the class in question and increment it in the init method?
This way you’ll have a definite count of the number of instances.
(Decrement it in the deinit() of course)
Failing that you could have a “global” variable type MyClass array in your appDelegate.
In your MyClass init, get a reference to your delegate, and have it add itself to the array.
Use weak references or decrement in Deinit to avoid double counting for dirty reassignment.
This way dead instances are released rather than being retained by the array.
This way you should have a count and list of instances.

Get Xamarin.iOS NSObject (new or cached) from IntPtr handle

In Xamarin documentation for Foundation.NSObject, in Lifecycle section, it says:
C# NSObjects are also created on demand when you invoke a method or a property that returns an NSObject. At this point, the runtime will look into an object cache and determine whether a given Objective-C NSObject has already been surfaced to the managed world or not. If the object has been surfaced, the existing object will be returned, otherwise a constructor that takes an IntPtr as a parameter is invoked to construct the object.
Is there a way to do the above from my code? In other words, given an IntPtr handle, can I get a C# NSObject if it already exists or let Xamarin create a new one if it doesn't?
The reason I want to do the above is that I want to keep the IntPtr handle of a C# NSObject and then Dispose() it. Later in the code, I want to get the NSObject back from that IntPtr.
The reason I want to do the above is that I've read enough documentation, blogs and SO questions about the interaction between the C# garbage collector and the native refcounted objects in Xamarin.iOS that I decided to Dispose() everything as soon as possible. So in all methods, I use using whenever I get an NSObject argument. For example:
[Foundation.Action("buttonPressed:")]
public void RatingButtonTapped(UIButton button) {
using (button) {
Console.WriteLine("Hello world");
}
}
So if I had kept a reference to the UIButton earlier during initialization, it will be disposed when this action is run. So instead, I plan to keep the IntPtr handle instead and re-get the UIButton when I need it later.
You can use this method to get the managed object for a handle:
ObjCRuntime.Runtime.GetNSObject (handle);
But have in mind that if the native object has been freed, you will crash.
If you don't want to crash, you need to retain the native handle, and then release it when you don't need it anymore.
If you add logic to retain+release the native handle, then you can just as well keep the managed object around, and only call Dispose when you determine you don't need the object anymore.
Curiously you link to the XY problem, and you're falling into that exact trap: your actual problem is that you have memory leaks (I assume, but you didn't explain), and you're asking about your attempted solution (dispose everything).
But that's the wrong solution to the problem. You will run into a world of pain with this solution (you've already found one, and if you go ahead with keeping handles around you'll end up in a much worse place: how to solve crashes instead of how to solve memory leaks).
The correct solution is:
Diagnose (and profile) to understand what's really happening (with the memory leaks).
Only dispose objects that you know are no longer needed (and that the GC couldn't already determine isn't needed). You want to dispose as little as possible (it makes your code easier to maintain), and you need to do step 1 first in order to know those objects.

Transferring the same object between ViewControllers

I have a class, User, that has an NSMutableArray that stores custom NSObjects. I only want one of these to ever be instantiated throughout the entire app, and I would like to be able to call methods on it in each ViewController for getting and setting. My problem is that I don't know how to call the methods so they apply to this one instance, instead of creating a new one each time. I'm new to objective-c, so the learning curve makes me feel I'm missing something a bit obvious. I've been working on this all day and am at a wit's end. Is there a good solution to my dilemma? Should I use a singleton class?
(If it helps, the class User is basically a class that stores a to-do list for each user that uses my app. The custom NSObjects are to-do items. There's probably a better storage method that should be used here, but I'm not sure what it is.)
RandomPleb it sounds like what you're looking for is a Singleton. http://en.wikipedia.org/wiki/Singleton_pattern. I also think this question has been answered before so search around on SO.
Laymen's terms; you create a static reference to the class that you only want one of inside that class, then make a static method in the following way:
//call this from classes that want to modify it
public static getsharedinstance()
{
if(the static instance of this class does not exist){
instantiate instance;
}
return this classes static instance..
}
Hope this helps (and if this is wrong, I hope someone can correct me)
Also in regards to your storing objects, I think NSMutableArray is fine unless it is a very big persistent list where each task has many properties in which case maybe using CoreData would be better.
Fenix

Confusion over running methods on Class Method instances of objects

So I'm getting myself into a confusion over where my data's going and where it's stored in my application. It's not a specific question so hopefully someone can provide a generalised answer.
I need to pass some data around between a few UIViewController instances, and I'm currently doing that with a singleton object called my dataManager. This class has one method, a class method, called + (LCDataManager *) sharedDataManager, and that method basically checks if whether the sharedDataManager already exists, if so, return it, if not, create it and set up its variables. This means that I can refer to that class anywhere I like, access and modify its variables anywhere I like, from across multiple classes.
First question: is this the correct / best / most appropriate means of passing data around like this? I'm hoping it obeys MVC, it feels like it does, and I hope I'm right.
Second question: what if I want to put an instance method in that class, and call it from within the class method? Let's say my sharedDataManager needs to call a method to grab some objects one of its variables (an array), and put them in another array, then send that back out again. I can't do that, can I? What's the way around that? If I make an instance of that class (rather than using the shared instance), I lose the ability to use that instance across multiple viewControllers.
I'm hideously confused, and it seems like it's not the problem I'm making it. Appreciate any guidance, and preferably not that "Read the Apple documentation" stuff – they write as if you already know what you're doing, and frankly I don't yet.
First question: is this the correct / best / most appropriate means of passing data around like this? I'm hoping it obeys MVC, it feels like it does, and I hope I'm right.
Your design is perfectly MVC compliant.
Second question: what if I want to put an instance method in that class, and call it from within the class method?
you can surely define an instance method and call it like this:
[[MyModelClass sharedModel] myInstanceMethod];
indeed, [MyModelClass sharedModel] will give you an instance of MyModelClass (which should be guaranted to be unique being it a singleton).
If you want to call the instance method from the sharedModel class method, you could also do that, because sharedModel owns a reference to your singleton, so it can send messages to it.
is this the correct / best / most appropriate means of passing data around like this?
There's nothing wrong with only having a single instance of LCDataManager, but using the Singleton pattern has potential problems. An alternative is to just initialize one LCDataManger and to pass it around to wherever it's needed.
what if I want to put an instance method in that class, and call it from within the class method?
The accessor + (LCDataManager *) sharedDataManager should only return the instance. I guess what you want is something like
+ (LCDataManager *)preparedDataManager {
LCDataManager *shared = [self sharedDataManager];
[shared doSomeInstanceMagic];
return shared;
}
- (void)doSomeInstanceMagic {
// magic!
// grab some objects one of its variables (an array),
// and put them in another array
}
Matthijs Hollemans has an excellent three-part tutorial on his blog about the correct way to make your view controllers talk to each other:
Part 1
Part 2
Part 3
there is no problem with this development architecture, and it is the must used (I think) in the iOS development. In the book IOS Programming: The Big Nerd Ranch Guide they call it Model View Controller Store.
Regarding your second question, yes, you can declare instance methods and call then from your sharedDataManager. What is not usual is creating other instances of a singleton class, but it is possible.

iOS - Clarifying class and instance methods

I just want to make sure I'm using class methods correctly.
By way of example, let's say I'm creating a game that involves a single map and individual tiles on that map (for instance, 16 x 16 tiles).
Each tile can consist of either a building, tree, road, etc - and this can change throughout the game.
Would I be correct in setting up a Map class with a class method to initialise the map, simply because there will only be one map and I would have no need to instantiate more than one?
Would I also be correct in setting up a Tile class with instance methods to initialise the tiles, because there would be 256 tiles each with their own properties?
Struggling to get my head around it all, any advice would be greatly appreciated.
There are multiple patterns for dealing with this, but basically it boils down to the Map class being a singleton. Some prefer to enforce the singleton-ness of the class by disallowing the creation of multiple instances (for example, by hiding the constructor, or making the constructor throw an exception, etc). In other cases it just suffices to document the Map class as being a singleton and use it as such.
A simple way of dealing with singletons in Objective-C is to create a class method for instantiating it, i.e.:
static Map* defaultMap = nil;
+ (Map*) defaultMap {
if(!defaultMap) defaultMap = [[Map alloc] init];
return defaultMap;
}
Using class methods for the map is probably not such a good idea, just like global variables is something that should usually be reduced to a minimum (though the example above is really a global variable, it will be a lot easier to refactor your code once you have a need for multiple maps).
Map class can be implemented as singleton pattern. Or any other way that limits it to only 1 shared instance.

Resources