OwnedArray object acces problems


#1

I have problems with owned array, i would like to pass those OwnedArryas between objects, i can’t access them when i do something like this

class Parent : public Component
{
     private:
       OwnedArray <myObject> objectList;
 
     public:
       OwnedArray <myObject> getList()
       {
            return (objectList);
       }

       int getListCount ()
       {
            return (objectList.size());
       }
};

class Child : public Component
{
     Parent *parent;
     public:
         Child (Parent *p)
         {
                parent = p;
          }

          void myMethod()
          {
               OwnedArray <myObject> list = parent->getList();
          }

          void myOtherMethod()
          {
                  parent->getListCount();
          }
}

all methods in the Child class fail, when i do the .size() method for an OwnedArray within the Parent class itself it’s ok but then the Child calls anything in the parent that touches the OwnedArray i get exceptions. I use VC6 i would like to know some universal way to deal with passing those OwnedArray’s around.

(this is all pseudo code i just wrote here :slight_smile: to just show the idea not the actual code)

i noticed that anything that touches the OwnedArry numUsed member causes an Exception like when i want to add an element to the array, but when i do .add() in the constructor of the Parent it’s ok no exceptions.


#2

You can’t make a copy of an OwnedArray, and the compiler should stop you even trying. The point about an OwnedArray is that it deletes the objects inside it, so having two of them owning the same objects would be treacherous.

Just pass a pointer or reference to it, or use an Array, or a ReferenceCountedArray.


#3

i get the same results with Array, but i guess Array is a bad idea since the objects i’d like to hold have a constructor and destructor and other complex methods, and the manual says they should be able to be memcp’ed, and that’s not the case.

what is weird that i hold the OwnedArray in an object and never try to pass the object itslef, so if i have a class Parent that has a memeber object that is a OwnedArray, i add a method to that Parent class that returns the size of that OwnedArray, it fails if that method is called from another object, but it does not fail if it’s called within that object (from any method of that object).

i don’t know why this happens, i use OwnedArray in the same program in other places and it works fine.


#4
#include <juce.h>

class myObject : public Component
{
	int x;

	public:
		myObject()
		{
			x = 1;
		}
		~myObject()
		{
		}
		void customMethod()
		{
			x = 230;
		}
		int getx()
		{
			return (x);
		}
};

class example    : public Component
{
	OwnedArray <myObject> objects;

	public:
		example()
		{
			objects.add (new myObject());
	    }
	    ~example()
	    {
	    }
		int mayhem()
		{
			for (int x=0; x<objects.size(); x++)
			{
				objects[x]->customMethod();
			}
	
			return (objects.size());
		}
		void crazy()
		{
			objects.add (new myObject());
		}
};

class child : public Component
{
	example *parent;

	public:
		child(example *p)
		{
			parent = p;
		}
		~child()
		{
		}
		void method()
		{
			Logger::writeToLog (String::formatted (T("Parent said: %d"), parent->mayhem()));
		}
		void nextMethod()
		{
			parent->crazy();
		}
};

class window  : public DocumentWindow
{
	public:
		window() : DocumentWindow (T("window"), Colours::lightgrey, DocumentWindow::allButtons, true)
		{
			example *p;

		    setContentComponent (p = new example());
	        setVisible (true);
			centreWithSize (400, 200);
	
			child *c = new child(p);
			c->method();
			c->nextMethod();
			c->method();
		}
		~window()
		{
		}
	    void closeButtonPressed()
	    {
			JUCEApplication::quit();
		}
};


class app : public JUCEApplication
{
    window *wnd;
	
	public:
	    app()
	    {
			wnd = 0;
		}
		~app()
		{
		}
	    void initialise (const String& commandLine)
	    {
			wnd = new window();
		}
		void shutdown()
		{
		    if (wnd != 0)
				delete wnd;
		}
		const String getApplicationName()
		{
	        return T("test");
	    }
		const String getApplicationVersion()
		{
	        return T("1.0");
	    }
		bool moreThanOneInstanceAllowed()
		{
	        return true;
		}
		void anotherInstanceStarted (const String& commandLine)
		{
		}
};

START_JUCE_APPLICATION (app)

this works, compiles and runs, writes to log 1 and then 2 the objects are added the method run, all is ok, but in my more complex program, the same idea fails. Is the fact that the above code works, just my “luck” and it really shouldn’t work ? or is this ok and i should look into my big program and find a bug there ?

edit:
i made it work, i think it was the TableListBoxModel base giving me problems not the OwnedArray, but the question is still valid, is this ok what i’ve written above, cause i use that in my code alot.


#5

your problem in your original code is that you have a function returning an OwnedArray. If you just want to access the contents of the array, you should either (a) provide access functions to do just that, or (b) return a REFERENCE to the OwnedArray. Remember that an owned array owns the objects; if you are to be ‘giving them away’ [i.e. retrieving the array is to place it somewhere else for keeps] then you would hold a pointer to one instead of having an actual member instance. However, the fact that you’re simply trying to return the array (rather than assign it to somewhere else) suggests that you only want to get access to it.

The simple modification you’d need is…

OwnedArray <myObject>& getList()
{
     return (objectList);
}

… if you knew that you didn’t want to modify the contents from outside its home, you could make it return a const OwnedArray&.

Depending on your circumstances/requirements, it might be safer to wrap the array up as much as possible. That usually means having accessor functions for all duties or, if you’re specifically trying to ‘pass the object around’ - wrapping it in some more descriptive/specific class as a special kind of ‘package’ [for example, a ‘Coach’ class containing Passenger objects - rather than simply an OwnedArray - would allow you to tailor the roving object to suit its taskset, and save on typing those anglebrackets everywhere (which begs alternatively for a simple typedef)!].

Perhaps if you’re more clear with your actual intentions causing the problem, we could provide more specific and relevant advice.


#6

The array holds pointers to Controller objects, each controller is a normal calss, with members that describe it’s type midi data, position, name, descritpion, and methods that make it work, when the controller changes value midi channel or whatever.

i need to pass this array between lower levels of my application (the core)to the gui so that it can draw how those controller look like, and also to the editor so that the editor can change the properties of each controller.

this looks more like so:

core [contains panels]-> panelCore [contains controllers] -> panelUi [draws panelCore]

both core and panelCore conatina OwnedArrays of panels and controllers (respectivly), sometimes instead of panelUi there is editorUi and/or editorControllerList (the editor is split in two parts, one edits the non UI parts of controllers, the other just the UI).

this is how it looks like more/less, i have no problem showing the code, but i’m pretty sure noone here has the time to get into it, but if that’s not the case please let me know.

a screenshot of how it looks like for now" http://relay.sndlab.com/filestore/x/ctrlr3.PNG

haydxn: thanks for the help, i was going to read “Design patterns” (i bought the book) but i had no time, from what i’ve looked into it there is a pattern with a wrapping class that propably could be of use to me, i will look into this definetly.