Pass unmanaged data around in managed code? - c++-cli

I'm building a Windows Form application that controls 3D volume rendering using an ArrayFire array object. The array is unmanaged. In the form constructor, I load and render the volume.
I have a Trackbar that controls the opacity of the volume and a corresponding scroll event handler. However, I can't figure out how to pass the volume array to the Trackbar scroll event handler so I can re-render the volume.
I can't make the volume array an attribute of the Form because, apparently, managed classes cannot have unmanaged attributes.
What's the best way to do this?

A managed class cannot have a field that is an unmanaged type, but it can have a field that is a pointer to an unmanaged type. Stick a * at the end of your unmanaged type, and you should be able to pass it to whatever methods you want, and store it wherever you want.

Related

Give an object transparency but still intractable (so can see other objects under it)

I've made an array of objects which I all want to preform an action when I'm interacting with a different object. Problem is that this overlaps the original object, yet I still want to see them. Basically what I want is an object which just acts as an invisible boundary, (like if I was to have a PictureBox over the top and set the image to Nothing and the BackColor as transparent (problem is that it appears transparency in windows forms doesn't exist and just makes it the form background colour)). Also setting Visible to False makes the object uninteractable.
TL;DR How do I make an object invisible but still intractable. Is there an object with the exact properties I'm describing I don't know about? Or a property to assign to an object. Thanks.

Object Assignment vs Object Creation

I have always found it hard to decide when I should create a single object and pass it to every object that needs it, or create a new object for every object which needs that item.
Some cases are so obvious, like entity objects which are readonly after allocation and instantiation. You can pass the same object anywhere and not worry about another object modifying it, which ruins the other objects holding a reference to it.
My problem mainly lies with objects that represent themselves to the user. Objects like CCSprite in cocos2d, NSMenuItem in Cocoa (AppKit) and other objects with visual representation..
Examples:
In cocoa, i know that I have to create an NSMenu for each NSPopUpButton, so that the selection for a specific button does not affect the rest. But, what about the NSMenuItems contained within? Can I create a single set and pass them to all the menus? What are your grounds, or how did you come to such a conclusion?
Other example:
In cocos2d, and almost all GUI based applications, you can pass to a button two images/sprites/...etc. such that one is for the normal state, and the other is for the selected (highlighted, pressed, clicked) state. Can I pass the same image/sprite/...etc. to both, making them point to the same object?
I hope this is not an implementation related issue (that it ultimately depends on the implementation) , since I face it in a lot of my programming projects, in cocoa, cocos2d, Java ... etc.
PS: I need help with choosing the proper tags
I suggest creating new instances unless doing this causes a performance problem. Sharing an NSMenuItem instance among many NSMenu makes it more difficulty to maintain control over that instance, which increases the risk of errors.

Reassigning properties when using ARC

I have a form with various controls. One of these controls lets the user change the category of the form being submitted via a modal view that appears after tapping on the control. When the user makes a selection to change the category of the form, the form needs to re-display the controls based on the new category.
Other than removing the previous controls from the form's view, is there anything I need to worry about in regards to the controls that are being discarded? Consider the following method that the form implements:
- (void)showControls
self.controls = [NSMutableArray array];
for(UIControl *control in self.dataSource.controls){
[self.controls addObject:control];
[self.view addSubview:control];
}
}
If I call this method multiple times (because the user changes the form category, as described earlier), I assume it results in various NSMutableArrays floating around without any pointers that reference them. Is this ok to do? I'm using ARC, so will it automatically collect those "lost" arrays?
ARC doesn't "collect" anything. Also, what you're doing there is fairly irrelevant that ARC is being used. You're using the setter for the control property which will work in the same way as pre-ARC. It will release the old value and retain the new value. So, you shouldn't have any problems with the arrays being "lost", unless you do weird things with self.controls other than what you've shown.

awakeFromFetch with non-managed property

I have an NSManagedObject subclass with some image data in an NSData property (imageData), which is automatically persisted. After loading the data from the network I also set a custom NSImage property (image) with an image created from the data.
The problem is that if the object is a fault, awakeFromFetch is not called when I access the image property, since it is not handled by Core Data. I can of course override the image accessor and make sure the properties are loaded (by accessing imageData) but it would be nice if there was a way to have awakeFromFetch invoked as normal. Any suggestions?
As per TechZen's suggestion, I now execute the fetch request with returnsObjectsAsFaults set to NO. It's of course not ideal to pull all data from the cache each time the object is fetched, but in my case I always use the data immediately so it's acceptable.
You seem to want to do two contradictory things, you want the main entity to remain fault but be able to access its attributes. You cannot do that. A fault by definition has not attributes/properties because it is just a placeholder in the object graph. If you want your main object to remain a fault, you should move the UIImage to its own entity and link it to the main object. You should then be able to walk the object graph to obtain the UIImage without triggering the loading of the main object's fault placeholder.

Core Data: When and where are Entities loaded in the first Place?

I have a question about Core Data. When starting my appliction, when is my data (which is stored automatically by Core Data) loaded into the NSArrayControllers? I want to modify it in the first place before the user can interact with it.
To be more specific: I have an NSArrayController for the entitity Playlist. Before the user can add new playlists or interact with the app at all, I want to modify the playlists programmatically. I tried windowControllerDidLoadNib: in my NSPersistentDocument (MyDocument.m) and awakeFromNib both in my NSPersistendDocument and the NSArrayController, but when I check in these methods with [[myArrayController arrangedObjects] count] I get 0 as result (the array controller's content is empty).
However, I actually have data stored and it is displayed to the user. I just do not know when and where I can modify it in the first place.
Thank your for any help.
Data is never "loaded" into the NSArrayController. The array controller is not an array itself. It does not contain or otherwise store data.
Instead, the array controller queries the object it is bound to for specific pieces of data only when that specific data is needed. This is especially true of Core Data in which managed objects are only fully instantiated when their attributes are accessed. The array controller moves data from an array type data structure to another object (usually an UI element.)
If you want to modify an existing store before it displays in the UI, you need to process the data before the array controller used by the UI is even initialized. If you're using NSPersistentDocument, then you can override readFromURL:ofType:error: to fetch and modify all your objects when the document is first opened. Alternatively, you can override the window controller's windowWillLoad or showWindow methods.
Regardless of where you do it, you must fetch all the managed objects you want to modify. You could programmatically create an array controller to do this but a fetch request is easier to micro manage if you have a large number of objects to modify.
You could try observing the "arrangedObjects" keypath of the controller and adding some logic to work that your array controller has been populated for the first time.
Another possible hook is implementing the awakeFromInsert/awakeFromFetch methods of your managed objects.