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 #31654 is a reply to message #31648] Fri, 18 March 2011 23:02 Go to previous messageGo to next message
Lance is currently offline  Lance
Messages: 526
Registered: March 2007
Contributor
mirek wrote on Fri, 18 March 2011 19:32


Sorry, but you would have hard time to convince me to go this way.

I guess the 'U++ legit' solution to this problem is to use Array.

struct Parent : ParentCtrl {
   Array<Ctrl> child;

   template<class T> T& Create() { T& x = child.Create<T>(); Add(x); return x; }
};


I believe that the moment you encourage using manual heap usage, the whole idea collapses. You start adding flags to what is owned and what is not everywhere and end in regular C/C++ heap mess, moments later wishing that you had garbage collector to deal with it... Smile

Mirek



I knew it's going to be a tough job Smile But there is a distinction between allowing and encouraging. Like smoking and drinking are still allowed in most countries but that doesn't mean their governments are encouraging the practices.

I have no doubt that the problem can be solved elegantly in the current U++ framework without introducing anything extra. TheIDE, which has a graphical designer allowing it to create children at users' requests is a good proof of such capability.

That being said, the solution you proposed has certain drawbacks. That container can only host Ctrl itself, or with some effort, we can make it to host objects of class derived from Ctrl without introducing any member variables. Beyond that, you need to provide a different container for almost every type of Ctrl derivatives that it will ever host. This fact alone will make Array<Ctrl> impractical.

Array<Ctrl*> is the next best alternative. Unfortunately Array<Ctrl*> will not delete the pointers it hold upon its destruction. Either we enclose it in a class to ensure pointed Ctrls are deleted or, we can store some smart pointer objects instead.

What if the situation requires many child be removed and added, ie., in a really dynamic situation? We probably need to use Index.

What do we gain from introducing an Array<Ctrl*> members or its Index version to keep track of dynamically created children at the cost of more memory space and CPU cycles? Virtually nothing.

Compare the two cases:

1. Owned children allowed. Simply Add(CtrlObject.Owned()); and RemoveChild(CtrlObject); Programmer understand there is a contract between him/her and the libaray, when he/she set the object as Owned, he/she surrenders the ownership to the containing object, just like he/she will sometimes ask a smart pointer object to take care of new'd objects
// when add
this->Add((new MySpeicalCtrl())->SizePosz(...).Owned());

// if the child is to destroy with *this, nothing
// further needs to be done, 
// however, if user interactions require it to be removed
// 
Ctrl * p = find_the_child_some_how();
this->RemoveChild(p);

// or more flexible, the program decide to take back ownership
Ctrl * p = find_the_child_some_how();
p->Owned(false);
this->RemoveChild(p);

// now p become freestanding, and it's the programmer's 
// responsibility to delete it when no longer needed, 
// or, find a new dad for it.


MySpecialCtrlContainer.Remove(actrl);
[/code]
2. Current status with no owning children support.
// when add
MySpecialCtrl * p=MySpecialCtrlContainer.Create();

// Setting up p properties
this->Add(*p);

// when remove
this->Remove(actrl);
MySpecialCtrlContainer.Remove(actrl);


[Updated on: Fri, 18 March 2011 23:15]

Report message to a moderator

Re: Proposed change to U++ to allow owning children. [message #31655 is a reply to message #31654] Fri, 18 March 2011 23:18 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
Lance wrote on Fri, 18 March 2011 18:02


That being said, the solution you proposed has certain drawbacks. That container can only host Ctrl itself, or with some effort, we can make it to host objects of class derived from Ctrl without introducing any member variables.




Totally untrue. You can put anything derived from Ctrl there without any compromises or efforts.

See

http://www.ultimatepp.org/reference$DynamicDlg$en-us.html

(and perhaps learn about U++ containers and Array flavor).

Mirek

[Updated on: Fri, 18 March 2011 23:20]

Report message to a moderator

Re: Proposed change to U++ to allow owning children. [message #31656 is a reply to message #31655] Fri, 18 March 2011 23:34 Go to previous messageGo to next message
Lance is currently offline  Lance
Messages: 526
Registered: March 2007
Contributor
Thank you for the quick reply. The example really amazed me. I guess I mixed Array with Vector. I didn't look into the code, but I guess Array introduced another layer so that like link list/map, etc, it doesn't require objects be stored in adjacent memory locations.

In the link you give to me, only Labels are stored in Array<Label>. But I don't dispute you. I will do a test to put Ctrl objects of different size to an Array<Ctrl>.


If that's the case, the additional costs to maintain dynamic object is not that hefty. But it still didn't solve the problem I raised regarding use cases where frequent insertion and deletion is needed.
Re: Proposed change to U++ to allow owning children. [message #31657 is a reply to message #31656] Fri, 18 March 2011 23:40 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
Lance wrote on Fri, 18 March 2011 18:34


If that's the case, the additional costs to maintain dynamic object is not that hefty. But it still didn't solve the problem I raised regarding use cases where frequent insertion and deletion is needed.


If you are concerned about Array::Remove/Insert costs, I believe that can easily work up to 10000 elements without issue.

If you get over that, you are dealing with some very special situation anyway and "owned" flag is not going to help you very much I believe.

[Updated on: Fri, 18 March 2011 23:41]

Report message to a moderator

Re: Proposed change to U++ to allow owning children. [message #31659 is a reply to message #31657] Sat, 19 March 2011 00:02 Go to previous messageGo to next message
Lance is currently offline  Lance
Messages: 526
Registered: March 2007
Contributor
Thank you very much! I have no doubt with U++'s speed. That's one big aspect why it attracts me.

Very informative.

Since you are here, how do you like my way of revised Ctrl::Ctrl implementation? Smile

Ctrl::Ctrl() {
	GuiLock __;
	LLOG("Ctrl::Ctrl");
	
    // a smarter way to implement this function
    // as we can see, most member variable to initialized
    // to 0, we can save a couple of cpu cycles by simply
    // zero out the part of object that are of POD type

    // Note Non-POD member variable frame, info, pos has been move to
    // follow POD members, with pos being the first non-pod member var.
    typedef int32 unit; // 4 should be deduced for flexibility
    unsigned size=((char*)&this->pos -(char*)this)/sizeof(unit); 
    for(unsigned i=0; i<size; ++i)
    	reinterpret_cast<unit*>(this)[i]=0;    

	
	//destroying = false;
	//owned = false;
	//parent = prev = next = firstchild = lastchild = NULL;
	//top = NULL;
	//exitcode = 0;
	frame.Add().frame = &NullFrame();
	enabled = visible = wantfocus = initfocus = true;
	editable = true;
//	GLX = false;
#ifdef PLATFORM_WIN32
	//activex = false;
	//isdhctrl = false;
#endif
	backpaint = IsCompositedGui() ? FULLBACKPAINT : TRANSPARENTBACKPAINT;
	//inframe = false;
	//ignoremouse = transparent = false;
	//caretcx = caretcy = caretx = carety = 0;
	//SetRect(Rect(0, 0, 0, 0));
	//inloop = popup = isopen = false;
	//modify = false;
	//unicode = false;
	//popupgrab = false;
	//fullrefresh = false;
	//akv = false;
	//hasdhctrl = false;
}
Re: Proposed change to U++ to allow owning children. [message #31660 is a reply to message #31659] Sat, 19 March 2011 00:37 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
Lance wrote on Fri, 18 March 2011 19:02

Thank you very much! I have no doubt with U++'s speed. That's one big aspect why it attracts me.

Very informative.

Since you are here, how do you like my way of revised Ctrl::Ctrl implementation? Smile



Slightly negative speed impact, saved about 100 bytes of .exe, dangerous w.r.t. code maintainance... Smile

Mirek
Re: Proposed change to U++ to allow owning children. [message #31662 is a reply to message #31660] Sat, 19 March 2011 01:30 Go to previous messageGo to next message
Lance is currently offline  Lance
Messages: 526
Registered: March 2007
Contributor
Thank you for giving it a try.

I was surprised to know there was actually a speed penalty. Maybe that's because of the for loop. Some really smarter compiler will tranlsate the for loop to movsb, movsw, movsdw, etc, then the for loop will no longer pose a speed penalty.

I was thinking set bit fields will be slower. Maybe just simple put the bitfields in a union and the whole flags field to 0.

Yes, the code will be harder to read and maintain. If somebody accidently add a non-pod data member into the area that's suppose to be POD members, he/she may be surprised.


A similar occasion.
[code]

Then here in the Draw.h
class Font : AssignValueTypeNo<Font, FONT_V, Moveable<Font> >{
	union {
		int64 data;
		struct {
			word  face;
			word  flags;
			int16 height;
			int16 width;
		} v;
	};
...

	Font()  { data=0; } // that's the whole point why
                            // a union is introduced IMHO


Re: Proposed change to U++ to allow owning children. [message #31663 is a reply to message #31662] Sat, 19 March 2011 01:35 Go to previous messageGo to next message
Lance is currently offline  Lance
Messages: 526
Registered: March 2007
Contributor
Sorry I am wasting your time. It's not worthy going further.

I still hold the belief that allowing a child to be owned by its parent is not a bad idea. But as the penalty for not allowing it is so small , there is no chance I can persuade you. So I give up. Smile

Re: Proposed change to U++ to allow owning children. [message #31670 is a reply to message #31662] Sat, 19 March 2011 10:59 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
Lance wrote on Fri, 18 March 2011 20:30

Thank you for giving it a try.

I was surprised to know there was actually a speed penalty. Maybe that's because of the for loop. Some really smarter compiler will tranlsate the for loop to movsb, movsw, movsdw, etc, then the for loop will no longer pose a speed penalty.



Nope, they are slightly slower than series of assignments.

Actually, smart compiler might unroll that loop into series of assignments anyway.

Quote:


I was thinking set bit fields will be slower. Maybe just simple put the bitfields in a union and the whole flags field to 0.



Now that would be smarter. Still, compiler are good, I would not be surprised if they replaced those assignements anyway.

Anyway, we are speaking here about negligible impacts on result (this area of code is definitely irrelevant optimization-wise).

But my primary complaint is that the loop is poor choice for quality of code, too error-prone.

Quote:


Then here in the Draw.h
class Font : AssignValueTypeNo<Font, FONT_V, Moveable<Font> >{
	union {
		int64 data;
		struct {
			word  face;
			word  flags;
			int16 height;
			int16 width;
		} v;
	};
...

	Font()  { data=0; } // that's the whole point why
                            // a union is introduced IMHO





Data is used to hash Font value and to compare it too.

Anyway, in any case there are 4 stable fields in union. Such situation is easily manageable.

Ctrl fields are much more numerous and change over time.
Re: Proposed change to U++ to allow owning children. [message #31691 is a reply to message #31670] Sun, 20 March 2011 10:32 Go to previous messageGo to next message
kohait00 is currently offline  kohait00
Messages: 939
Registered: July 2009
Location: Germany
Experienced Contributor
i am dealing with the same issue, and will, if fortunate, provide a no-need-to-touch-upp solution soon..using a container interface and a template approach, so you can safely handle the stuff with Array<Ctrl>

just a hint, i myself where trying to convince mirek of things several times Smile. his experience is hard to beat. upp demands/suggests to give up some long existing (and maybe errorprone) programming habbits. the benefit (especially when using upp) is clear code, simple model approach and a high degree of code readability (and thus maintainability). take your time to get familiar with upp and its way to handle things. you quite soon gonna love it. it saves you a lot of hassle (just to mention a few: no pointer hassle, memleaks almost never (everything belongs somewhere) and a sophisticated serialisation/marshalling mechanism. upp is well thought out, and the things mirek is defending are part of a long run design process which prooved to be reliable.

cheers Smile

[Updated on: Sun, 20 March 2011 10:33]

Report message to a moderator

Re: Proposed change to U++ to allow owning children. [message #31694 is a reply to message #31691] Sun, 20 March 2011 14:07 Go to previous messageGo to next message
Lance is currently offline  Lance
Messages: 526
Registered: March 2007
Contributor
Thanks, kohait00! As mirek has demonstrated, it's not hard.

The only issue is if it's worthy. Paying the cost of an additional container ( I didn't look into Array implementation, from its interface, it's probably an Vector of pointers pointing to individually allocated objects. The user would not feel a difference. But still there are memory cost & speed cost paid.) so that Upp libary users can do without manual new/delete, that's something I cannot appreciate at my current level or mindset.

It's really a philosophical/religious difference. Many ones believe pointers are evil, Java go as far as do away with it completely, but that doesn't make the small bunch us to leave C++ and embrace it.

C++ also encourages using its library and smart pointers to minimize the chances to use new or have to keep track of new'ed objects. But it certainly doesn't go as far as declaring new/delete a privilege of library developers only.

Anyway, this is really unimportant. As I have said, we stand no chance to convince mirek, who have achieved so much with the sticking to his philosophy, plus the cost is but minimal.
Re: Proposed change to U++ to allow owning children. [message #31695 is a reply to message #31694] Sun, 20 March 2011 14:11 Go to previous messageGo to next message
Lance is currently offline  Lance
Messages: 526
Registered: March 2007
Contributor
BTW, I like the IDE facility (probably by overloading global new/delete) to detect memory leak in debug mode. It's very convenient and considerate.
Re: Proposed change to U++ to allow owning children. [message #31696 is a reply to message #31695] Sun, 20 March 2011 14:28 Go to previous messageGo to next message
Lance is currently offline  Lance
Messages: 526
Registered: March 2007
Contributor
It just come to me that we can change the interface slightly to make it unnecessary/impossible for end users to use new directly.

Add a template member function to the Ctrl class

class Ctrl...
{
...
     bool owned : 1;
....
protected:
    bool IsOwned()const{ return owned; }
    Ctrl& Owned(bool v){ owned=v; return *this; }

public:
    template <typename ChildType>
    ChildType& AddOwned()
    {
        ChildType* p=new ChildType();
        p->Owned();
        (void)Add(p);
        return *p;
    }


    template <typename ChildType, typename T>
    ChildType& AddOwned(T& t)
    {
        ChildType* p=new ChildType(t);
        p->Owned();
        (void)Add(p);
        return *p;
    }

    // return ChildType so that user can further set its
    // properties.

    // The IsOwned and Owned functions will be demoted to protected
    // so that they are available only to libary developers
    //
    // whether a child is owned is a one time decision.
    // an owned child will not be able to be reverted to unowned
    // by end user (without derive from the Ctrl class or its 
    // derivatives), but he/she is free to change parents for it
    //
    // Unless the end user uses some hackish practice,
    // library developers can be assured the owned flag
    // is reliable and predictable. 
};

[Updated on: Sun, 20 March 2011 15:17]

Report message to a moderator

Re: Proposed change to U++ to allow owning children. [message #31765 is a reply to message #31696] Fri, 25 March 2011 13:26 Go to previous messageGo to next message
kohait00 is currently offline  kohait00
Messages: 939
Registered: July 2009
Location: Germany
Experienced Contributor
still interested in that topic?

i think having owned Ctrls just like that wont do much, since you have to know/reference the controls somehow/somewhere, you will end up traversing the child link tree, and doing dynamic_casts allover.

ultimate is heavily based on compile time connection of the application parts, means, if you have a Ctrl and place it somewehere, then you probably will hook up some static (not runtime specific) functionality to it, within your code.

a heap creation of Ctrls implys some sort of dynamic application behavior. for what the controls need to be fairly straight forward in handling, i.e. only Get/SetData interface unsing, only WhenAction Callback using, etc.. anything else is too specific.

i basicly have the same problem. that's why some time ago, i started the CtrlProp package in bazaar. a uniform api to query/control some properties of Controls, without actually knowing its type.

another project i am currently takling is the generation / modification of Controls in its position, a control factory so to say, which would be extended using *decorator* design pattern.
meanwhile see the CtrlPos package. which is part of it.

maybe thats sth you can use as well. see also FormEditor, which is another nice work, from someone else.

as soon as the ctrl factory is in a fitting shape i'll provide it in bazaar.

cheers
Re: Proposed change to U++ to allow owning children. [message #31782 is a reply to message #31765] Sun, 27 March 2011 15:33 Go to previous messageGo to next message
Lance is currently offline  Lance
Messages: 526
Registered: March 2007
Contributor
kohait00:

Sounds interesting. Please let me know when you do.

Thanks,
Lance
Re: Proposed change to U++ to allow owning children. [message #32020 is a reply to message #31782] Sun, 17 April 2011 17:25 Go to previous messageGo to next message
kohait00 is currently offline  kohait00
Messages: 939
Registered: July 2009
Location: Germany
Experienced Contributor
in my journey exposing core elements of upp to python i ran into this issue again. it'd make things really easy, if a control can own another.

in python, the idea of using only a known set of interfaces when dealing with Ctrl is crucial, to be able to make dynamic guis, where Value is the core data element (which is pretty much what a Python object is). a python exported Ctrl is instanced by python interpreter and is able to manage the instance itself or transfer the owning to another facility. creating ctrl instances in python is crucial, when decorating ctrl functionality with python means is desired..

but maybe exporting upp ctrls to python will also benefit from the stuff i described before (the additional dont-touch-upp layer).

anyway, maybe this should be reconsidered.

[Updated on: Sun, 17 April 2011 17:27]

Report message to a moderator

Re: Proposed change to U++ to allow owning children. [message #32038 is a reply to message #32020] Tue, 19 April 2011 06:00 Go to previous messageGo to next message
Lance is currently offline  Lance
Messages: 526
Registered: March 2007
Contributor
We'll probably not going to see owned children in Upp any time soon. But this problem HAS been elegantly solved: Interface similar to Array::Create<ChildType>() to avoid end user having to use new operator; virtually no additional cost except a couple of cpu cycles; no existing code will be broken.

Please let me know if I am wrong Smile
Re: Proposed change to U++ to allow owning children. [message #32046 is a reply to message #32038] Tue, 19 April 2011 09:14 Go to previous messageGo to next message
kohait00 is currently offline  kohait00
Messages: 939
Registered: July 2009
Location: Germany
Experienced Contributor
where can i see this interface? you dont mean mine Smile
Re: Proposed change to U++ to allow owning children. [message #32053 is a reply to message #32046] Tue, 19 April 2011 14:09 Go to previous messageGo to next message
Lance is currently offline  Lance
Messages: 526
Registered: March 2007
Contributor
In post 31696. I change the interface so that using new is no longer required and no longer permitted. When user wants a child to be owned(thus destroyed) by its parent, he/she uses the following way:

     parent.AddChild<Label>().SetLabel("Hello world!")
                     .PosRight(...).PosTop(...);
     Button& b=parent.AdddChild<Button>.SetLabel("Click Me!");
     b<<THISBACK(ButtonClicked);




Non-owned child controls are still added in the old way.
Re: Proposed change to U++ to allow owning children. [message #32058 is a reply to message #32053] Tue, 19 April 2011 18:05 Go to previous messageGo to previous message
kohait00 is currently offline  kohait00
Messages: 939
Registered: July 2009
Location: Germany
Experienced Contributor
now got you..

though it's nice the way you planned it, the way upp handles ownership in containers i.e. is a bit different.

there, the implicit rule of thumb is (asuming Array is used)
that a pointer denotes a freshly created element (see Add(T* x) function in Array) for which the container needs to take ownership. moreover, there is the Detach() function, returning the pointer indicating that ownership has been stopped and the user needs to take care of that element again.

sth like this should also be expected from the ownership interface for Ctrl (if anytime to come).

IMHO ownership is not usefull in a C++ only / static environment (where no controls are created and thus nothing needs to be deleted). they are defined in Layout and done.

for dynamic environment OTOH, where controlls with a reduced set of api (GetData,SetData,WhenAction Callback) are created and destroyed in a deliberate manner, ownership would improove codeability.. (especially thinking about scripting layouts, like my current intent: Python).

thus maybe mirek can help with some ideas. but it needs to be thought out well, since it touches the upp philosophy..

BTW: as soon as the last little fix from CtrlLib is online, i'll post here a current environment, for dynamic control handling, like promised.

Previous Topic: Get MAC addresses for windows and linux
Next Topic: Testing framework in U++.
Goto Forum:
  


Current Time: Fri Mar 29 15:51:46 CET 2024

Total time taken to generate the page: 0.02140 seconds