Thread: [litwindow-users] Using aggregate/accessors
Status: Alpha
Brought to you by:
hajokirchhoff
From: yrs90 <yr...@ya...> - 2005-04-19 05:19:05
|
On accessing items: I tried the following code. Too bad, I can't create a debug build and use a debugger. wxListCtrl *pList = wxDynamicCast(event.GetEventObject(), wxListCtrl); aggregate ag(make_aggregate(*pList)); accessor ac(ag["Items"]); if (ac.is_valid() && ac.is_container()) { container c = ac.get_container(); // yeah, it worked... etc. } else if(ac.is_valid() && ac.is_aggregate()) { wxMessageBox("is an aggregate"); } else if(ac.is_valid()) { wxMessageBox("valid but not a container"); } else { wxMessageBox("not valid"); } This code returns 'valid but not a container'. Before I put the is_container() check in, it generated a runtime error. In a separate problem, I added a constructor/destructor to an otherwise unchanged class that I pass to the framework and suddenly I started getting runtime access violations. Is there some type of change to the ADAPTER declaration required when there is a constructor in the class? I'll send additional details if the answer solution isn't immediately apparent. Best regards, Joel --- [This E-mail scanned for viruses by Declude Virus] |
From: Hajo K. <mai...@ha...> - 2005-04-19 06:17:24
|
yrs90 wrote: > This code returns 'valid but not a container'. Before I put the > is_container() check in, it generated a runtime error. What do you pass to "Items"? > In a separate problem, I added a constructor/destructor to an otherwise > unchanged class that I pass to the framework and suddenly I started getting > runtime access violations. Is there some type of change to the ADAPTER > declaration required when there is a constructor in the class? No requirements for adding a constructor/destructor. Must be a problem on your side. Have you tried rebuilding? BTW, you will get lost very quickly without a debugger. If you cannot afford the Visual Studio Standard edition and if you are adventureous you could download the visual studio .NET 2005 C++ Express version and use that debugger there (I think it has one). It should be able to debug code generated by the free MS tools, provided the free tools let you switch on debugging information. Not having a debugger is not really an option IMHO for something so new as the lit window library. Best regards Hajo |
From: yrs90 <yr...@ya...> - 2005-04-19 07:16:16
|
> > This code returns 'valid but not a container'. Before I put the > > is_container() check in, it generated a runtime error. > What do you pass to "Items"? I am passing a vector<class MyListData> to Items. Specifically, RULE("xrcMainList.Items", make_expr<accessor>("m_ListData")) Where vector<MyListData> m_ListData; BEGIN_ADAPTER(DataClass) PROP(m_ListData) END_ADAPTER() IMPLEMENT_ADAPTER_CONTAINER(vector<MyListData>) At least, m_items.is_container() == true, because the FillList() function is populating the wxListCtrl and it only populates the list if m_items.is_container() is true. > No requirements for adding a constructor/destructor. Must be a problem > on your side. Have you tried rebuilding? Yes I made sure to do a clean rebuild. I'll look at it more closely after I get further along. > Not having a debugger is not really an option IMHO for something so new > as the lit window library. Yes, I agree. I only have this problem building debug versions if I use LitWindow and consequently STL. Using a debugger is possible as it is, but it is quite tedious to use without symbol tables. Unfortunately I have to factor in the cost of buying new tools for a couple of C-runtime libraries into the decision about whether to commit to using LitWindow. I'll take a look at the VC 2005 Express Beta to see if that will resolve the immediate need. Thanks, Joel --- [This E-mail scanned for viruses by Declude Virus] |
From: yrs90 <yr...@ya...> - 2005-04-19 07:46:05
|
> No requirements for adding a constructor/destructor. Must be a problem > on your side. Ah, found it. Indeed a problem on my side. In my constructor I called an internal clear function in which I call NotifyChanged(). :/ Obviously, it is hard to notify a half-constructed object. Thanks, Joel --- [This E-mail scanned for viruses by Declude Virus] |
From: Hajo K. <mai...@ha...> - 2005-04-19 08:48:27
|
Hi, >>What do you pass to "Items"? > > > I am passing a vector<class MyListData> to Items. > > Specifically, > > RULE("xrcMainList.Items", make_expr<accessor>("m_ListData")) ah, of course. Tiny detail, big effect. I didn't pay close enough attention. You are not passing a vector<>, you are passing an accessor to a vector. Thats the same difference between Type and Type*. The accessor is like Type*. You need to dereference the accessor to get to the vector. On the wxListCtrl side: Items is not a vector<MyListData>, its an accessor, which in your situation currently happens to point at a vector<MyListData> but could point to a totally different data type a few microseconds later. So you have wxListCtrl *pList = wxDynamicCast(event.GetEventObject(), wxListCtrl); aggregate ag(make_aggregate(*pList)); accessor ac(ag["Items"]); ag["Items"] returns an accessor to the property. If the property is of type long, it returns an accessor to a long object. If the property is of type string, it returns an accessor to a string object. In your case, the property is an accessor, so ag["Items"] returns an accessor to an accessor object. To get to the real accessor, the one you are interested in, you must dereference the accessor, much like *ag["Items"]. But accessors are untyped objects, so you need to cast it into a typed accessor first, then dereference it. Here is how: typed_accessor tac=dynamic_cast_accessor<accessor>(ac); accessor the_real_items_accessor=tac.get(); // this is like '*ac' the_real_items_accessor.is_container()==true; I'll rewrite the scenario using pseudo-code and replace accessor with 'void*' to make things more clear. wxListCtrl *pList=wxDynamicCast... aggregate ag(make_aggregate(*pList)); // ag["Items"] returns a void* to the "Items" member property // which is itself of type void* // so ag["Items"] return type is void ** void **ac=ag["Items"]; // ag.Items // cast it so we can get to the data void *tac=*(void*)ac; vector<MyDataStruct> *the_real_items_accessor=(vector<...>*)tac; *** Here is the full version again, that should work now: wxListCtrl *pList = wxDynamicCast(event.GetEventObject(), wxListCtrl); aggregate ag(make_aggregate(*pList)); accessor ac(ag["Items"]); typed_accessor tac=dynamic_cast_accessor<accessor>(ac); accessor the_real_items=tac.get(); if (the_real_items.is_valid() && the_real_items.is_container()) Looks more complicated than it is until you think of accessors as void* pointers with type information, which is exactly what they are by the way :) Hajo |