How to edit controls in a system::thread. - c++-cli

I need to be able to add items to a listbox inside of a thread. Code is below:
1. ref class Work
2. {
3. public:
4. static void RecieveThread()
5. {
6. while (true)
7. {
8. ZeroMemory(cID, 64);
9. ZeroMemory(message, 256);
10. if(recv(sConnect, message, 256, NULL) != SOCKET_ERROR && recv(sConnect, cID, 64, NULL) != SOCKET_ERROR)
11. {
12. ID = atoi(cID);
13. String^ meep = gcnew String(message);
14. lbxMessages->Items->Add(meep);
15. check = 1;
16. }
17. }
18. }
19. };
I get the error
Error: a nonstatic member reference must be relative to a specific object on line 14. Is there any way to get it to let me do that? Because if I try to use String^ meep; outside of that Thread it doesn't contain anything. It works PERFECT when I use it within the thread but not outside of it. I need to be able to add that message to the list-box. If anyone can help I would appreciate it.

You don't show how lbxMessages is defined, but I'm going to assume that it's a non-static data member in the same class. If that's the case, then you need to specify which object you want to access lbxMessages on. The simplest way would be to switch the RecieveThread method to be non-static, then you can access this->lbxMessages.
You didn't say which windowing toolkit you're using, but you probably will need to Invoke back onto the UI thread in order to edit the control.

One way is using System::Thread with a ParameterizedThreadStart delegate, which let you pass objects, in this case lbxMessages.
ParameterizedThreadStart^ threadCallback;
threadCallback = gcnew ParameterizedThreadStart(&Work::ReceiveThread);
Thread^ recvThread = gcnew Thread( threadCallback );
recvThread->Start( lbxMessages );
Your static method for running the thread:
static void RecieveThread(Object^ state)
{
ListBox^ lbxMessages = (ListBox^)state;
//...code
}
But.. . there is another problem. Assuming ListBox is a Win32 control, you can make changes in control only from the thread which it was created. So every time you insert a ListBox item, it must be done from the UI's thread. One way is using a SynchronizationContext object.
// Start the thread
array<Object^>^ args = gcnew array<Object^>(2){
lbxMessages,
SynchronizationContext::Current
}
recvThread->Start( args);
Thread method should be something like this:
static void RecieveThread(Object^ state)
{
array<Object^>^ args = (array<Object^>^)state;
ListBox^ lbxMessages = (ListBox^)args[0];
SynchronizationContext^ ctx = (SynchronizationContext^)args[1];
//...code
String^ meep = gcnew String(message);
ctx->Send(gcnew SendOrPostCallback(&Work::SafeListBoxInsert),
gcnew array<Object^>(2){lbxMessages, meep}
);
}
You will need another method to be called from UI's thread and make the changes.
ref class Work{
//...other methods
static void SafeListBoxInsert(Object^ state)
{
array<Object^>^ args = (array<Object^>^)state;
ListBox^ lst = (ListBox^) args[0];
String^ item = (String^) args[1];
lst->Items->Add(item);
}
}

Related

Repast: cannot call method from another class in Context Builder

I dont know why I get NullPointerException:
ERROR [AWT-EventQueue-0] 18:21:05,864 repast.simphony.ui.RSApplication - Error while initializing simulation
java.lang.NullPointerException
at intraCity_Simulator.GlobalScheduler.load_data(GlobalScheduler.java:20)
at intraCity_Simulator.Initialization_Builder.build(Initialization_Builder.java:306)
at repast.simphony.dataLoader.engine.ClassNameContextBuilder.build(ClassNameContextBuilder.java:41)
Below is the code. The query works when I put it directly in the initialization (context builder) but when I put this code in another class and call it in the context builder it reports NullPointerException.
public void load_data() {
Context<Object> context = ContextUtils.getContext(this);
Iterable<Object> readers = context.getObjects(DataReader.class);
DataReader this_reader = null;
Query<Object> reader_query = new PropertyEquals<Object>(context, "name", "parcel");
for (Object o : reader_query.query()) {
if (o instanceof DataReader) {
this_reader = (DataReader) o;
}
}
System.out.print(this_reader.getName());
}
when I do this in context builder it reports nullPointerException
GlobalScheduler gs = new GlobalScheduler();
context.add(gs);
gs.load_data();
UPDATE:
I just find the line "Context context = ContextUtils.getContext(this);" is not working. the context is still being null. Why? But I need this line as the query needs the context as a parameter.
However, if I follow your suggestion to pass the context directly into the method load_data() it works.
public void load_data(Context context) {
// Context<Object> context = ContextUtils.getContext(this);
DataReader this_reader = null;
System.out.println("context " + context);
Query<Object> reader_query = new PropertyEquals<Object>(context, "name", "parcel");
for (Object o : reader_query.query()) {
System.out.println(o);
if (o instanceof DataReader) {
this_reader = (DataReader) o;
}
}
System.out.print(this_reader.getName());
}
Why can I not be able to identify the context using "Context context = ContextUtils.getContext(this);" ? This method works if it is called as a method in step() but fails if it is called as method in Context Builder.
What's actually null there? Without that its hard to tell if this is a repast question or just fixing a null pointer error. If its the latter, it should be easy enough to determine what variable is null, and then why it is so.
That said, you probably don't need this line
Context<Object> context = ContextUtils.getContext(this);
if you are calling it in the ContextBuilder -- just pass in the context to load_data(). That would at least avoid the context being null.

How to return data from a BackgroundWorker in c++?

I've got a BackgroundWorker continually reading data from a USB device. I want to parse that data, then feed it back to my main GUI thread to update a plot and save it to a file.
I suspect the way to do this is using ReportProgress, but I'm not sure how to pass an object as required.
Here's a snippet of what I'm trying to do:
class Datapacket
{
public:
int Val1;
double Val2;
}
backgroundWorker_DoWork(Object^ sender,DoWorkEventArgs^ e)
{
// readUSB
.........
// create Datapacket with values from usb stream:
Datapacket dp;
dp.Val1 = 5;
dp.Val2 = 34.6;
backgroundWorker->ReportProgress(0, dp); // this bit fails to compile
}
backgroundWorker_ProgressChanged(Object^ sender, ProgressChangedEventArgs^ e)
{
Datapacket dp = e.dp ??????
// update gui, etc
textBox_Data->Text = dp.Val1.ToString();
}
I usually use c#, so diving into this in C++ is a minor headache as it is!
You're near. Datapacket is not a .NET reference type (class) and I'd assume you do not want to dispose it when it's out of scope. Change it to ref class and just add ^ in your backgroundWorker_DoWork (and change . with -> where appropriate):
backgroundWorker_DoWork(Object^ sender,DoWorkEventArgs^ e)
{
Datapacket^ dp = gcnew Datapacket();
dp->Val1 = 5;
dp->Val2 = 34.6;
backgroundWorker->ReportProgress(0, dp);
}
In your event handler you just need to cast UserState property to original type (and change . with -> where appropriate):
backgroundWorker_ProgressChanged(Object^ sender, ProgressChangedEventArgs^ e)
{
Datapacket^ dp = dynamic_cast<Datapacket^>(e->UserState);
// update gui, etc
textBox_Data->Text = dp->Val1.ToString();
}
Do not forget to set WorkerReportsProgress to true.

Controller selection

In my title screen, i have a code saying that the first controller using A is the PlayerIndex.one.
Here is the code:
public override void HandleInput(InputState input)
{
for (int anyPlayer = 0; anyPlayer <4; anyPlayer++)
{
if (GamePad.GetState((PlayerIndex)anyPlayer).Buttons.A == ButtonState.Pressed)
{
FirstPlayer = (PlayerIndex)anyPlayer;
this.ExitScreen();
AddScreen(new Background());
}
}
}
My question is: How can i use the "FirstPlayer" in other classes? (without this, there is no interest in this code)
I tried the Get Set thing but i can't make it work. Does i need to put my code in another class? Do you use other code to make this?
Thanks.
You can make a static variable say : SelectedPlayer,
and assign first player to it!
then you can call the first player through this class,
for example
class GameManager
{
public static PlayerIndex SelectedPlayer{get;set;}
..
..
..
}
and right after the loop in your code, you can say:
GameManager.SelectedPlayer = FirstPlayer;
I hope this helps, if your code cold be clearer that would be easier to help :)
Ok, so to do this properly you're going to have to redesign a little.
First off, you should be checking for a new gamepad input (i.e. you should be exiting the screen only when 'A' has been newly pressed). To do this you should be storing previous and current gamepad states:
private GamePadState currentGamePadState;
private GamePadState lastGamePadState;
// in your constructor
currentGamePadState = new GamePadState();
lastGamePadState = new GamePadState();
// in your update
lastGamePadState = currentGamePadState;
currentGamePadState = GamePad.GetState(PlayerIndex.One);
Really what you need to do is modify your class that deals with input. The basic functionality from your HandleInput function should be moved into your input class. Input should have a collection of functions that test for new/current input. For example, for the case you posted:
public Bool IsNewButtonPress(Buttons buton)
{
return (currentGamePadState.IsButtonDown(button) && lastGamePadState.IsButtonUp(button));
}
Then you can write:
public override void HandleInput(InputState input)
{
if (input.IsNewButtonPress(Buttons.A)
{
this.ExitScreen();
AddScreen(new Background());
}
}
Note: this will only work for one controller. To extend the implementation, you'll need to do something like this:
private GamePadState[] currentGamePadStates;
private GamePadState[] lastGamePadStates;
// in your constructor
currentGamePadStates = new GamePadState[4];
currentGamePadStates[0] = new GamePadState(PlayerIndex.One);
currentGamePadStates[1] = new GamePadController(PlayerIndex.Two);
// etc.
lastGamePadStates[0] = new GamePadState(PlayerIndex.One);
// etc.
// in your update
foreach (GamePadState s in currentGamePadStates)
{
// update all of this as before...
}
// etc.
Now, you want to test every controller for input, so you'll need to generalise by writing a function that returns a Bool after checking each GamePadState in the arrays for a button press.
Check out the MSDN Game State Management Sample for a well developed implementation. I can't remember if it supports multiple controllers, but the structure is clear and can easily be adapted if not.

How can I use nested Async (WCF) calls within foreach loops in Silverlight?

The following code contains a few nested async calls within some foreach loops. I know the silverlight/wcf calls are called asyncrously -but how can I ensure that my wcfPhotographers, wcfCategories and wcfCategories objects are ready before the foreach loop start? I'm sure I am going about this all the wrong way -and would appreciate an help you could give.
private void PopulateControl()
{
List<CustomPhotographer> PhotographerList = new List<CustomPhotographer>();
proxy.GetPhotographerNamesCompleted += proxy_GetPhotographerNamesCompleted;
proxy.GetPhotographerNamesAsync();
//for each photographer
foreach (var eachPhotographer in wcfPhotographers)
{
CustomPhotographer thisPhotographer = new CustomPhotographer();
thisPhotographer.PhotographerName = eachPhotographer.ContactName;
thisPhotographer.PhotographerId = eachPhotographer.PhotographerID;
thisPhotographer.Categories = new List<CustomCategory>();
proxy.GetCategoryNamesFilteredByPhotographerCompleted += proxy_GetCategoryNamesFilteredByPhotographerCompleted;
proxy.GetCategoryNamesFilteredByPhotographerAsync(thisPhotographer.PhotographerId);
// for each category
foreach (var eachCatergory in wcfCategories)
{
CustomCategory thisCategory = new CustomCategory();
thisCategory.CategoryName = eachCatergory.CategoryName;
thisCategory.CategoryId = eachCatergory.CategoryID;
thisCategory.SubCategories = new List<CustomSubCategory>();
proxy.GetSubCategoryNamesFilteredByCategoryCompleted += proxy_GetSubCategoryNamesFilteredByCategoryCompleted;
proxy.GetSubCategoryNamesFilteredByCategoryAsync(thisPhotographer.PhotographerId,thisCategory.CategoryId);
// for each subcategory
foreach(var eachSubCatergory in wcfSubCategories)
{
CustomSubCategory thisSubCatergory = new CustomSubCategory();
thisSubCatergory.SubCategoryName = eachSubCatergory.SubCategoryName;
thisSubCatergory.SubCategoryId = eachSubCatergory.SubCategoryID;
}
thisPhotographer.Categories.Add(thisCategory);
}
PhotographerList.Add(thisPhotographer);
}
PhotographerNames.ItemsSource = PhotographerList;
}
void proxy_GetPhotographerNamesCompleted(object sender, GetPhotographerNamesCompletedEventArgs e)
{
wcfPhotographers = e.Result.ToList();
}
void proxy_GetCategoryNamesFilteredByPhotographerCompleted(object sender, GetCategoryNamesFilteredByPhotographerCompletedEventArgs e)
{
wcfCategories = e.Result.ToList();
}
void proxy_GetSubCategoryNamesFilteredByCategoryCompleted(object sender, GetSubCategoryNamesFilteredByCategoryCompletedEventArgs e)
{
wcfSubCategories = e.Result.ToList();
}
Yes, before you can proceed with the next step of the algorithm, you need to have gotten the result of the previous step, which can be hard when you have to use the async methods.
If this is not happening on the UI thread, then you could just block and wait for the response. For example, have each "completed" method signal (using whatever synchronization primitives are available in Silverlight; I don't know offhand e.g. if ManualResetEvent is there, if so, have the completed callback call .Set()), and then have your main PopulateControl method invoke the FooAsync() call and then block until the ManualResetEvent signals (by calling .Wait()).
If this is on the UI thread and you really need to write a non-blocking solution, then it is much, much harder to code this up correctly in C#. You might consider using F# instead, where asyncs provide a nice programming model for non-blocking calls.
EDIT:
Pseudo-code example to block for results:
// class-level
ManualResetEvent mre = new ManualResetEvent(false);
// some method that needs to make WCF call and use results
void Blah() {
// yadda yadda
proxy.FooCompleted += (o,ea) => { ... mre.Set(); };
proxy.FooAsync(...);
mre.WaitOne(); // block until FooCompleted
// use results from FooCompleted now that they're here
// mre.Reset() if you intend to use it again later
}
I used a lambda for FooCompleted, but using a separate method like you have is fine too.
Alternatively, for each async method you are using to populate the collection you can create a helper method that would return IObservable and then use Linq query to group the result.
E.g.:
private IObservable<Photographer> GetPhotographerNames()
{
var photographers = Observable
.FromEvent<GetPhotographerNamesCompletedEventArgs>(proxy, "GetPhotographerNamesCompleted")
.Prune()
.SelectMany(e => e.EventArgs.Result.ToObservable());
proxy.GetPhotographerNamesAsync();
return photographers;
}
And similarly:
private IObservable<Category> GetCategoryNamesFilteredByPhotographer(int photographerId) { ... }
private IObservable<SubCategory> GetSubCategoryNamesFilteredByCategory(int photographerId, int categoryId) { ... }
Now you can write a Linq query:
var pcs = from p in GetPhotographerNames()
from c in GetCategoryNamesFilteredByPhotographer(p.PhotographerId)
from s in GetSubCategoryNamesFilteredByCategory(p.PhotographerId, c.CategoryId)
select new {p, c, s};
This query will return you a list of triplets (Photographer, Category, SubCategory) Now all you have to do is to Subscribe to it and aggregate it to the objects you use on the client which should be pretty straightforward.

How do I express a void method call as the result of DynamicMetaObject.BindInvokeMember?

I'm trying to give a short example of IDynamicMetaObjectProvider for the second edition of C# in Depth, and I'm running into issues.
I want to be able to express a void call, and I'm failing. I'm sure it's possible, because if I dynamically call a void method using the reflection binder, all is fine. Here's a short but complete example:
using System;
using System.Dynamic;
using System.Linq.Expressions;
class DynamicDemo : IDynamicMetaObjectProvider
{
public DynamicMetaObject GetMetaObject(Expression expression)
{
return new MetaDemo(expression, this);
}
public void TestMethod(string name)
{
Console.WriteLine(name);
}
}
class MetaDemo : DynamicMetaObject
{
internal MetaDemo(Expression expression, DynamicDemo demo)
: base(expression, BindingRestrictions.Empty, demo)
{
}
public override DynamicMetaObject BindInvokeMember
(InvokeMemberBinder binder, DynamicMetaObject[] args)
{
Expression self = this.Expression;
Expression target = Expression.Call
(Expression.Convert(self, typeof(DynamicDemo)),
typeof(DynamicDemo).GetMethod("TestMethod"),
Expression.Constant(binder.Name));
var restrictions = BindingRestrictions.GetTypeRestriction
(self, typeof(DynamicDemo));
return new DynamicMetaObject(target, restrictions);
}
}
class Test
{
public void Foo()
{
}
static void Main()
{
dynamic x = new Test();
x.Foo(); // Works fine!
x = new DynamicDemo();
x.Foo(); // Throws
}
}
This throws an exception:
Unhandled Exception:
System.InvalidCastException: The
result type 'System.Void' of the
dynamic binding produced by the object
with type 'DynamicDemo' for the binder
'Microsoft.CSharp.RuntimeBinder.CSharpInvokeMemberBinder'
is not compatible with the result type 'System.Object' expected by the
call site.
If I change the method to return object and return null, it works fine... but I don't want the result to be null, I want it to be void. That works fine for the reflection binder (see the first call in Main) but it fails for my dynamic object. I want it to work like the reflection binder - it's fine to call the method, so long as you don't try to use the result.
Have I missed a particular kind of expression I can use as the target?
This is similar to:
DLR return type
You do need to match the return type specified by the ReturnType property. For all of the standard binaries this is fixed to object for almost everything or void (for the deletion operations). If you know you're making a void call I'd suggest wrapping it in:
Expression.Block(
call,
Expression.Default(typeof(object))
);
The DLR used to be quite lax about what it would allow and it would provide some minimal amount of coercion automatically. We got rid of that because we didn't want to provide a set of convensions which may or may not have made sense for each language.
It sounds like you want to prevent:
dynamic x = obj.SomeMember();
There's no way to do that, there'll always be a value returned that the user can attempt to continue to interact with dynamically.
I don't like this, but it seems to work; the real problem seems to be the binder.ReturnType coming in oddly (and not being dropped ("pop") automatically), but:
if (target.Type != binder.ReturnType) {
if (target.Type == typeof(void)) {
target = Expression.Block(target, Expression.Default(binder.ReturnType));
} else if (binder.ReturnType == typeof(void)) {
target = Expression.Block(target, Expression.Empty());
} else {
target = Expression.Convert(target, binder.ReturnType);
}
}
return new DynamicMetaObject(target, restrictions);
Perhaps the callsite expects null to be returned but discards the result - This enum looks interesting, particularly the "ResultDiscarded" flag...
[Flags, EditorBrowsable(EditorBrowsableState.Never)]
public enum CSharpBinderFlags
{
BinaryOperationLogical = 8,
CheckedContext = 1,
ConvertArrayIndex = 0x20,
ConvertExplicit = 0x10,
InvokeSimpleName = 2,
InvokeSpecialName = 4,
None = 0,
ResultDiscarded = 0x100,
ResultIndexed = 0x40,
ValueFromCompoundAssignment = 0x80
}
Food for thought...
UPDATE:
More hints can be gleaned from Microsoft / CSharp / RuntimeBinder / DynamicMetaObjectProviderDebugView which is used (I presume) as a visualizer for debuggers. The method TryEvalMethodVarArgs examines the delegate and creates a binder with the result discarded flag (???)
Type delegateType = Expression.GetDelegateType(list.ToArray());
if (string.IsNullOrEmpty(name))
{
binder = new CSharpInvokeBinder(CSharpCallFlags.ResultDiscarded, AccessibilityContext, list2.ToArray());
}
else
{
binder = new CSharpInvokeMemberBinder(CSharpCallFlags.ResultDiscarded, name, AccessibilityContext, types, list2.ToArray());
}
CallSite site = CallSite.Create(delegateType, binder);
... I'm at the end of my Reflector-foo here, but the framing of this code seems a bit odd since the TryEvalMethodVarArgs method itself expects an object as a return type, and the final line returns the result of the dynamic invoke. I'm probably barking up the wrong [expression] tree.
-Oisin
The C# binder (in Microsoft.CSharp.dll) knows whether or not the result is used; as x0n (+1) says, it keeps track of it in a flag. Unfortunately, the flag is buried inside a CSharpInvokeMemberBinder instance, which is a private type.
It looks like the C# binding mechanism uses ICSharpInvokeOrInvokeMemberBinder.ResultDiscarded (a property on an internal interface) to read it out; CSharpInvokeMemberBinder implements the interface (and property). The job appears to be done in Microsoft.CSharp.RuntimeBinder.BinderHelper.ConvertResult(). That method has code that throws if the aforementioned ResultDiscarded property doesn't return true if the type of the expression is void.
So it doesn't look to me like there's an easy way to tease out the fact that the result of the expression is dropped from the C# binder, in Beta 2 at least.