Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » Developing U++ » U++ Developers corner » Proposed change to U++ to allow owning children.
Re: Proposed change to U++ to allow owning children. [message #32069 is a reply to message #32058] Wed, 20 April 2011 02:44 Go to previous messageGo to next message
Lance is currently offline  Lance
Messages: 526
Registered: March 2007
Contributor
Adding Detach is a piece of cake.

Something like this:
Ctrl& Ctrl::Detach()
{
     if(owned)
     {
         owned=false;
         parent->RemoveChild(this);
     }
     return *this;
}


I intentionally disallow all subsequent changing owned state capabilities so that it appears less dangerous/error-prone. If nobody can detach it, its destruction by its parent is guaranteed. Changing parent will not break the mechanism. Detach and leave alone will open the door for memory leak.
Re: Proposed change to U++ to allow owning children. [message #32073 is a reply to message #32069] Wed, 20 April 2011 08:51 Go to previous messageGo to next message
kohait00 is currently offline  kohait00
Messages: 939
Registered: July 2009
Location: Germany
Experienced Contributor
Lance wrote on Wed, 20 April 2011 02:44

Adding Detach and leave alone will open the door for memory leak.


Detach is dangerous, but it's there and sometimes needed. the coder has to have the possibility to handle stuff in fair custom ways as well. the containers do have it too.

could you provide the files with all the latest changes as one? i'm bit lazy to collect it.. i'd like to review it maybe can get some idea..thanks in advance

cheers
Re: Proposed change to U++ to allow owning children. [message #32078 is a reply to message #32073] Wed, 20 April 2011 19:24 Go to previous messageGo to next message
Lance is currently offline  Lance
Messages: 526
Registered: March 2007
Contributor
Will do.

I am working on something I called RecordSet/Dynamic Struct, maybe a reinvention of wheel. But it keeps really busy.
Re: Proposed change to U++ to allow owning children. [message #32079 is a reply to message #32058] Wed, 20 April 2011 21:17 Go to previous messageGo to next message
Lance is currently offline  Lance
Messages: 526
Registered: March 2007
Contributor
I didn't backup my original work. Basically I have to redo what has been done.

Overwrite the Upp libary version of Ctrl.cpp CtrlCore.h CtrlChild.cpp (or whatever names) with attached version. Backup before proceed.

BTW, those files are in $(UPPMAIN)/uppsrc/CtrlCore directory.

Attached is also a test program. How do I know it works? No news is good news: had there been memory leak, our honest TheIDE will not forget to prompt us.

[Updated on: Wed, 20 April 2011 21:26]

Report message to a moderator

Re: Proposed change to U++ to allow owning children. [message #32080 is a reply to message #32079] Wed, 20 April 2011 21:23 Go to previous messageGo to next message
Lance is currently offline  Lance
Messages: 526
Registered: March 2007
Contributor
Out put of sample program:

index.php?t=getfile&id=3192&private=0

And the main content of the sample program:

using namespace Upp;

class MyLabel : public Label
{
public:
	MyLabel(String& s){ SetLabel(s); }
};


struct ButtonApp : TopWindow {

	ButtonApp()	: count(0)
	{		
		Sizeable().Zoomable();
		Click();
	}

	void Click()
	{
		int x, y;
		Ctrl * p;
		x=count%max_row_button*(button_width+5)+2;
		y=count/max_row_button*(button_height+5)+2;
		
		if( count & 1)
			p=&NewChild<MyLabel>(String().Cat()<<"["<<count<<"] A Label");
		else
		{
			p=&NewChild<Button>()
				.SetLabel(String().Cat()<<"["<<count<<"] Click Me");
			*(Button*)p<<=THISBACK(Click);
		}
				
		p->LeftPos(x,button_width).TopPos(y,button_height);

		++count;
	}

	typedef ButtonApp CLASSNAME;

private:
	const static int button_width=180;
	const static int button_height=40;
	const static int max_row_button=5;

	int    count;
};

GUI_APP_MAIN
{
	ButtonApp().Run();
}
Re: Proposed change to U++ to allow owning children. [message #32081 is a reply to message #32080] Wed, 20 April 2011 21:38 Go to previous messageGo to next message
Lance is currently offline  Lance
Messages: 526
Registered: March 2007
Contributor
Detach is implemented as protected. Intended for libary developer or person who knows how to handle it as it opens the door for possible leaks!

Also, there is one step I omitted. The owned flag should be unset in Ctrl copy constructor. If pick semantics is guaranteed, this will not be an issue. There is something we need to worry about only when there is prospect that the fix will be included into the library.

The reason being, a programmer may copy a dynamically created Ctrl to a stack allocated object. If this happen, the owned flag is wrongfully set and will lead to memory corruption. The move constructor (pick semantics) should always be preferred. The copy constructor should be "protected" so that it's available only to library developer or person know its potential danger.
Re: Proposed change to U++ to allow owning children. [message #32160 is a reply to message #32081] Thu, 28 April 2011 16:32 Go to previous messageGo to next message
kohait00 is currently offline  kohait00
Messages: 939
Registered: July 2009
Location: Germany
Experienced Contributor
just as promised here comes my current test package, it's really a test package.

it can create on the fly new controls (which are meant to be hooked to a specific interface which is not yet finished). the gui can be saved and restored.

just a short description:
* go to live work tab
* click small rectangle at top left in view area, this will switch to edit mode
* click some control, it becomes selected and the properties are displayed and can be modified on the fly (live work)
* moving can be performed just as used from RectCtrl, if ever tried, use STRG, SHIFT as modifiers to restrict movements..
* while moving a control, hold ALT to move it *into* another, adding it as child, or move it outside its parent.. very fluid.

* the bottom frame of view area has got a Ctrl prototypes factory, it uses the same moving + hold ALT means to place the prototype onto the surface of another control or view area. the factory recreates the control in its own view area again.
* moving + hold ALT a control from somewhere into the factory again will leave it there pending for delete. the next control moved to the factory will toggle a remove of the previous. thus you can move a 'deleted' control back to surface if you change your mind.

* i'm extending the current Ctrl with an interface that manages the ownership of similar controls. it wont own Ctrl's that are not derived from that interface.

beeing already said its only my test environment. it's not complete. but it's what i plan to do. basicly inspired from
jazzmutant's lemur control (if ever heared of it, thus a python console is to be included there as well, see BoostPyTest in bazaar).

let me know if that goes in your direction.
i admit, Ctrl having ownership means would greatly simplify this all.

revised ownership change [message #32161 is a reply to message #32160] Thu, 28 April 2011 18:28 Go to previous messageGo to next message
kohait00 is currently offline  kohait00
Messages: 939
Registered: July 2009
Location: Germany
Experienced Contributor
hi Lance

i've gone though the code and based on your work redid it.
current state is attached.

the scenarios are basicly theese:

1) normal scenario (current upp)
Ctrls are added to arbitrary context to be displayed, ownership context is maintained somewhere else. -> 2 different contexts, perfect control over whats happening. for complex environment.

2) ownership scenario (additional)
heap created controls can be added to other controls that will maintain their lifetime together with their visual context. means, when an owned Ctrl is removed from its owning parent, the parent is taking care of destruction. so both contexts, visual and ownership are bound. fits well for dynamic environment with reduced Ctrl API usage (GetData/SetData, WhenAction, etc)

features

* traditional upp way still default
* ownership adding (AddOwned, Detach) is only interface for dealing with ownership (similar to containers)
* auto transfer of ownership supported when an owned Ctrl is added to another parent.
* least intrusive code
* drawback: owned controls may not call Remove(), since their parent will try to delete them. ASSERT placed. arguable.. use Detach for that.. or specify implicit Detach with Remove?

changes to your version:

* removed template creators, not needed for ownership management.
* code cleanup and simplification
* redefined public interface for ownership (mainly: no public Owned(bool b true) method, veeery dangerous)
* some ASSERTS placed to ensure proper behaviour and early fault catch
* delete only in one place.. avoids some conrercases when context switching.

take a look..
maybe mirek will be really considering it. at least look at it Smile
Re: revised ownership change [message #32167 is a reply to message #32161] Thu, 28 April 2011 21:45 Go to previous messageGo to next message
Lance is currently offline  Lance
Messages: 526
Registered: March 2007
Contributor
Good job.

Except the template creator should be kept. It's simulating the Array::Create<ChildType>() interface. Look at it this way, a Ctrl is a special type of container: it references some of its children while owning (responsible for their destruction) some others. Since allowing library user to change the owned flag is regarded as unsafe, and use of new/delete by library users is generally discouraged, it makes sense to have a similar Create/Detach interface like does Array.

The point of the template creator (NewChild, AddOwned, CreateOwned or whatever we may choose to call it) is to eliminate the necessity of asking end user to supply a new'ed object, instead of:
    parent.AddOwned(new Button());

now use
    parent.CreateOwned<Button>();
    //
    // similar to 
    // anArray.Create<Button>();
    //


Yes, any access to owned flag should be protected. That's my true intention. Thanks for fixing it.


I still think that to expose Detach to public scope is not a good idea. It should be protected and only accessible through inheritance. Even though it works in common/reasonable senario:

1. a Ctrl is Detached from its parent:
In any case, the Ctrl is removed from its parent's children list. If the Ctrl has owned flag set, a pointer to it will be returned so that user code will be responsible for its eventual destruction; if its a normal stack resident Ctrl. a NULL pointer will be returned to signal the user not to try to delete it afterwards.

2. the user delete's the detached Ctrl after finished using it. No problem, expected scenario.

3. the user decide to add the ctrl to another Ctrl as child by way of Add(), AddChild(), etc. Since the owned flag is correctly set, the new parent will be responsible for its destruction.

So it seems no hole is introduced. But here Add(), AddChild() becomes ambiguous to the user. The user may form an impression that Add()/AddChild() can be supplied with any new'ed Ctrls without the user to worry about their eventual destruction. To avoid this confusion, maybe it's best to simply hide it from library users.

Re: revised ownership change [message #32168 is a reply to message #32167] Thu, 28 April 2011 21:57 Go to previous messageGo to next message
kohait00 is currently offline  kohait00
Messages: 939
Registered: July 2009
Location: Germany
Experienced Contributor
for Create<> i go with you..

for Detach i disagree. there is no point in offering Ownership ability to Ctrl without offering the complete interface to manupulate it. calling RemoveChild() would delete the child. so there is actually no way to safely get the owned ctrl back from there.

the question is
should Detach be handled explicitly or should a Remove() call on an owned child be seen as detaching it?

i think the later is quite logical, but it'd leave dangeling references in places Remove is used without the awareness of dealing with a floating reference.

[Updated on: Thu, 28 April 2011 23:03]

Report message to a moderator

Re: revised ownership change [message #32169 is a reply to message #32168] Thu, 28 April 2011 23:18 Go to previous messageGo to next message
Lance is currently offline  Lance
Messages: 526
Registered: March 2007
Contributor
Personally I don't dislike Detach at all. It's hard to think of a situation where Detach causes problem more than Array::Detach does. The only problem is that it will make the code harder to understand for somebody who doesn't go deep enough on this topic.

And if a Child control can be Detached, could it be reattached to another parent? If the answer is not, than Detach would be perfectly fine. If the answer is yes, essentially you open the door for add a user newed object which Mirek objects.

So either:
1. Call parent.CreateOwned<ChildType>() to create the object on heap and add as parent's child;
2. When the child is expected to be killed, hide it, access all its properties, and call parent.Remove(..)

or
1. Call parent.CreateOwned<ChildType>() to create the object on heap and add as parent's child;
2. When the child is no longer needed, Detach it and remember the returned poiter.
3. Access its properties, and delete it manually. 



The advantage of case 2 over case 1 is that it allow the parent be destructed while the child remain valid, think about the case where the parent itself is its parent's dynamically created child.

The disadvantage of case 2 over case 1 is that it requires the library user to use delete. But since he/she has to delete the object returned by Array::Detach, it should not hurt that much.

If you agree with my above analysis, I go with case 2 too. Or do you have other recommendation?
Re: revised ownership change [message #32170 is a reply to message #32169] Thu, 28 April 2011 23:31 Go to previous messageGo to next message
Lance is currently offline  Lance
Messages: 526
Registered: March 2007
Contributor
In either case 1 or 2, a CreatedOwned child can change parent like any other stack Ctrl without losing track. So this is not a concern. Or, change parent is perfectly defined behavior for either type of children.

If we go with Case 2, CreateOwned+Detach, a detached child should never be reattached to a parent [by calling AddChild(...) etc]. It's a final decision, you detach it, you destruct it. However, Derived class can reattach by way of protected member function.

This is a virtually zero cost, safe, and consistent solution as far as I can see.

Regarding the hole when copying/picking(yes, picking also requires reset the owned flag), we can tinker the Ctrl pick constructor a little bit to fix it.
Re: revised ownership change [message #32171 is a reply to message #32170] Thu, 28 April 2011 23:54 Go to previous messageGo to next message
Lance is currently offline  Lance
Messages: 526
Registered: March 2007
Contributor
In the rare case where we are destructing its parent but could not make up our mind whether we are going to delete it or assign it to yet another parent (not decided at the moment), we can use a dirty trick to circumvent the no-reattachment limitations,

{
   // p is pointed to a dynamically created child

   ParentCtrl tmp;
   tmp.Add(p); // or should it be *p? I rely on TheIDE on this
               // now p is no longer part of its previous parent's
               // child tree.

   // Destruct its previous parent to free precious memory resource :)
   // and since *p belongs somewhere else, it will not be touched.

   // a thousand lines/function calls to make up our mind whether
   // we are going to destruct *p or add it to another parent.

   if( newdad !=NULL)
       newdad->Add(p);

   // we don't even need to detach and delete, as p will be 
   // destructed with tmp at the end of the code block
   // if a newdad is not successfully found.
   // this is the expected behavior

}

[Updated on: Thu, 28 April 2011 23:59]

Report message to a moderator

Re: revised ownership change [message #32502 is a reply to message #32171] Sun, 22 May 2011 21:58 Go to previous messageGo to next message
kohait00 is currently offline  kohait00
Messages: 939
Registered: July 2009
Location: Germany
Experienced Contributor
i think mirek wont let this happen, because there is really quite a lot of flaws in it ispecially the Remove() call of an owned Ctrl is a huge problem. since this would delete the Ctrl itself. if not, it would dangle. but there are a lot of handling expecting the Ctrl to continue to exist after calling Remove() on it.

so thats why i will procure in developping my LiveWork environment..

have you tried it?
Re: revised ownership change [message #32503 is a reply to message #32502] Mon, 23 May 2011 00:28 Go to previous messageGo to next message
Mindtraveller is currently offline  Mindtraveller
Messages: 917
Registered: August 2007
Location: Russia, Moscow rgn.
Experienced Contributor

I think U++ owning system is far more efficient than ordinary approach. So I wouldn't recommend embed QT-style management of controls.

It is better learning better approaches than creating patches to allow old-style programming. Believe me, it is worth your efforts.

Some time ago I've made an article and had discussion about it here (it's in Russian)
http://habrahabr.ru/blogs/cpp/111259/

[Updated on: Mon, 23 May 2011 00:32]

Report message to a moderator

Re: revised ownership change [message #32511 is a reply to message #32503] Mon, 23 May 2011 11:16 Go to previous messageGo to next message
kohait00 is currently offline  kohait00
Messages: 939
Registered: July 2009
Location: Germany
Experienced Contributor
i agree. will take the effort to read it, though living in germany i originate from kazachstan Very Happy

the upp approach is worth gold (everything belongs somewhere) and some old habbits die hard.. that's why i decided to use a distinct interface class to manage ownership. this will make it esier anyway.

i'm often tempted to drive upp towards the object base /polymorphism approach i.e. like in C# and forget about upp hard type checks.. which is the source of it's beauty and speed.

any polumorphism should be handled extra, in the specific containers.
Re: revised ownership change [message #32750 is a reply to message #32502] Mon, 06 June 2011 05:05 Go to previous messageGo to next message
Lance is currently offline  Lance
Messages: 526
Registered: March 2007
Contributor
kohait00 wrote on Sun, 22 May 2011 21:58

i think ispecially the Remove() call of an owned Ctrl is a huge problem. since this would delete the Ctrl itself. if not, it would dangle. but there are a lot of handling expecting the Ctrl to continue to exist after calling Remove() on it.




For example? Do you mean UPP library code relying on the continued existence of a control after it's been removed from its parent, or, user code, as a common practice, may access a dynamic control's properties after it's been removed (hence deleted) from its parent?

I agree the latter is an issue as it's against Upp programmer's habit.

I was really busy. I know there are lots of good stuff in the bazzar worth trying and learning, but I will have to wait.
Re: revised ownership change [message #32751 is a reply to message #32503] Mon, 06 June 2011 05:11 Go to previous message
Lance is currently offline  Lance
Messages: 526
Registered: March 2007
Contributor
Mindtraveller wrote on Mon, 23 May 2011 00:28

I think U++ owning system is far more efficient than ordinary approach. So I wouldn't recommend embed QT-style management of controls.

It is better learning better approaches than creating patches to allow old-style programming. Believe me, it is worth your efforts.

Some time ago I've made an article and had discussion about it here (it's in Russian)
http://habrahabr.ru/blogs/cpp/111259/


True. With my limited experience with U++, I never need to dynamically allocate a control. A common situation would be to create UI from , eg., XML, but in that case, a dedicated container like an hash map would be more efficient as it will be frequently required to access controls by their names/IDs.

My believe is that it's of virtual no cost but may of some use some time.
Previous Topic: Get MAC addresses for windows and linux
Next Topic: Testing framework in U++.
Goto Forum:
  


Current Time: Tue Apr 23 08:19:31 CEST 2024

Total time taken to generate the page: 0.02418 seconds