How to get hand position on Hololens? - position

I have this script in order to get hand position with hololens, but it does not work and it gives me this error:
Errore CS0123 Nessun overload per 'GetPosition' corrisponde al delegato 'Action'
Can someone help me ?
This is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.WSA.Input;
public class Hand : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
void Awake()
{
InteractionManager.InteractionSourcePressed += GetPosition; // No overload for 'GetPosition' corresponds to delegate 'Action<InteractionSourcePressedEventArgs>'
}
private void GetPosition(InteractionSourceState state)
{
Vector3 pos;
if (state.sourcePose.TryGetPosition(out pos))
{
Debug.Log(pos);
}
}
}

The error code pointed out that if you want to register for the InteractionSourcePressed input event, you should modify the callback function GetPosition to match the delegate of the InteractionSourcePressed event.
So, in this case, you can refer to the following code to fix this issue:
private void GetPosition(InteractionSourceState state)
=>
private void GetPosition(InteractionSourcePressedEventArgs args)
More information please see:Windows-specific APIs (XR.WSA.Input)

Related

How do I replace Asynctask with RxJava Observer?

I have a test project with Room database. Using Asynctask I can successfully insert an object with some test data into the database. I'm trying to learn RxJava and replace Asynctask with RxJava's observer, but it doesn't work. I have read alot of documentation and watched tutorials, but I don't think I quite get it. Here's the relevant code:
Here I set my Room object with the data from my List:
for(ObjectForArray item: listToDatabase) {
myRoomEntity.setName( item.getName() );
Log.d( "TAG", myRoomEntity.getName() );
}
Then I try to use RxJava Observable to insert data into the database. This was originally and successfully done using Asynctask:
Observable<MyRoomEntity> myRX = Observable
.just(myRoomEntity)
.subscribeOn( Schedulers.io() )
.observeOn( AndroidSchedulers.mainThread() );
myRX.subscribe( new Observer<MyRoomEntity>() {
#Override
public void onSubscribe(Disposable d) {
Log.d("TAG ONSUBSCRIBE", d.toString());
try {
myViewModel.insertDatabase( myRoomEntity );
Log.d( "TAG", "Populating database Success" );
}catch(Error error) {
Log.d( "TAG", error.toString() );
}
}
The OnNext, OnError and OnComplete are empty.
When I run the project it crashes with the error:
Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
I'm obviously using RxJava wrong since the point is to do asynchronous tasks away from the main thread.
i have use RX java in replace of Asyntask as it has been deprecated in android 9
there are multiple replacements that android provides like Executors, threads, Listenable Futures , Coroutines 🔥, so you are looking how to implement this with rxjava and how RX Java java helps your to migrate just add these dependencies first in gradle
implementation "io.reactivex.rxjava2:rxjava:2.2.20"
implementation "io.reactivex.rxjava2:rxandroid:2.1.1"
once you import lets start working with RX java i will let you know where you can put background task, pre execute, on post execute like asynctask
lets start codding with Rx java first , i have comment in the method that will help you to put the code
Observable.fromCallable(new Callable<Boolean>() {
#Override
public Boolean call() throws Exception {
/// here is your background task
return true;
}
}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Boolean>() {
#Override
public void onSubscribe(Disposable d) {
//// pre execute here is my progress dialog
showProgressDialog(getString(R.string.scanning));
}
#Override
public void onNext(Boolean aBoolean) {
//// here is on sucess you can do anystuff here like
if (aBoolean){
/// if its value true you can go ahead with this
}
}
#Override
public void onError(Throwable e) {
/// this helps you to go if there is any error show dialog whatever you wants here
Log.e("error of kind",e.getMessage() );
}
#Override
public void onComplete() {
/// when your task done means post execute
}
});
once its done lets start working with implementation
Observable.fromCallable(new Callable<Boolean>() {
#Override
public Boolean call() throws Exception {
/// here is your background task
uribitmap = getScannedBitmap(original, points);
uri = Utils.getUri(getActivity(), uribitmap);
scanner.onScanFinish(uri);
return true;
}
}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Boolean>() {
#Override
public void onSubscribe(Disposable d) {
//// pre execute here is my progress dialog
showProgressDialog(getString(R.string.scanning));
}
#Override
public void onNext(Boolean aBoolean) {
//// here is on sucess you can do anystuff here like
if (aBoolean){
/// if its value true you can go ahead with this
}
}
#Override
public void onError(Throwable e) {
/// this helps you to go if there is any error show dialog whatever you wants here
Log.e("error of kind",e.getMessage() );
}
#Override
public void onComplete() {
/// when your task done means post execute
uribitmap.recycle();
dismissDialog();
}
});
now i will do this with executors :
/// pre execute you can trigger to progress dialog
showProgressDialog(getString(R.string.scanning));
ExecutorService executors = Executors.newSingleThreadExecutor();
executors.execute(new Runnable() {
#Override
public void run() {
//// do background heavy task here
final Bitmap uribitmap = getScannedBitmap(original, points);
uri = Utils.getUri(getActivity(), uribitmap);
scanner.onScanFinish(uri);
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
//// Ui thread work like
uribitmap.recycle();
dismissDialog();
}
});
}
});
You are getting this error because you are trying to insert an Object on the main (UI) thread.
You should do something like this:
Observable.fromCallable(() -> myViewModel.insertDatabase( myRoomEntity ))
.subscribeOn( Schedulers.io() )
.observeOn( AndroidSchedulers.mainThread() );
And then use an Observer to subscribe to the Observable.
Please try restructuring your code like this:
Completable.fromAction(() -> myViewModel.insertDatabase(myRoomEntity))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(() -> Log.d("TAG", "Populating database Success"),
throwable -> Log.d("TAG", throwable.toString()))
Considerations:
If your myRoomEntity is not available before this whole construct gets subscribed, make sure you use defer http://reactivex.io/documentation/operators/defer.html
Your subscribe section handlers are operating on "main", that's why you were receiving a crash.
If possible, avoid unnecessary just calls

What's the alternative of onAfterLayout() of GXT2 in GXT3?

I migrate a project from GXT2 to GXT3. I can't find an alternative of the method onAfterLayout(). Any one have an idea please?
One option is to onAttach handler with a schedule deferred wrapped around a function should provide the behavior you want in the next event loop.
final GridWithRadiosWidget grid = new GridWithRadiosWidget();
grid.asWidget().addAttachHandler(new Handler() {
#Override
public void onAttachOrDetach(AttachEvent event) {
if (grid.asWidget().isAttached()) {
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
#Override
public void execute() {
// Do something in the next event loop after it's rendered
}
});
}
}
});
And another option is to extend the layout container and extend onResize.

How do I get a method and KeyEventArgs interact with each other?

I am trying to learn programming for fun (apologies in advance if I get the terminology wrong) and have found an issue that I am struggling to solve. I have been trying to get a program to interact with key a key being pressed (e.g: you press "space" and the console will print "hello world") and am unable to get the event and method to interact.
What am I doing wrong; is it a simple step I've missed or have I got the structure completely wrong?
Thank you!
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Key_Input_2
{
class MainProgram
{
static void Main(string[] args)
{
KeyInput_2 k = new KeyInput_2();
bool keyType = k.dKey_KeyDown();
if (keyType == true)
{
Console.WriteLine("Hello World");
}
}
}
class KeyInput_2
{
bool dKey = false;
public bool dKey_KeyDown(object sender, KeyEventArgs e)
{
while (dKey == false)
{
if (e.KeyCode == Keys.D)
{
return true;
}
else
{
return false;
}
}
}
}
}
Start with this:
public bool dKey_KeyDown()
{
var key = Console.ReadKey();
if (key == ConsoleKey.D)
{
return true;
}
else
{
return false;
}
}
The code you have posted won't work at all.
First, you are calling dKey_KeyDown without any arguments, but the declaration of this method requires two arguments, object sender, and KeyEventArgs e...so the code won't even compile, let alone run.
Second, it looks like you might have copied and pasted this from some example code from Windows Forms coding; in this case sender and e are supplied by the Forms code as part of its event handling mechanism. I won't go into the details here, but it won't work in a Console application..you can read more about it here
In the interest of helping out, here is a simple program that will do what you want, it uses Console.ReadKey
using System;
namespace SimpleKey
{
class Program
{
static void Main(string[] args)
{
//make a variable to store the input from the user's keypress
ConsoleKeyInfo input = new ConsoleKeyInfo();
//keep executing the code inside the block ({..}) until the user presses the Spacebar
while (input.Key != ConsoleKey.Spacebar)
{
Console.WriteLine("Press SpaceBar...");
input = Console.ReadKey();
}
//now they have pressed spacebar, so display the message
Console.WriteLine("Hello World");
}
}
}
Finally - congratulations on deciding to take up programming! Stick with it, you'll be glad you did :)

MvvmCross binding iOS Gestures

I'm searching a way how can i bind ios gesture like UILongPressGestureRecognizer to ICommand or MvxCommand in MvvmCross, thanks.
PS : I found an example here but i can't figure out how to do that.
From the example you found and from the current MVVM Cross source I did the following
public static class MvxBehaviourExtensions
{
public static MvxLongPressGestureRecognizerBehaviour LongPress(this UIView view)
{
var toReturn = new MvxLongPressGestureRecognizerBehaviour(view);
return toReturn;
}
}
and
public class MvxLongPressGestureRecognizerBehaviour
: MvxGestureRecognizerBehavior<UILongPressGestureRecognizer>
{
protected override void HandleGesture(UILongPressGestureRecognizer gesture)
{
// Long press recognizer fires continuously. This will ensure we fire
// the command only once. Fire as soon as gesture is recognized as
// a long press.
if (gesture.State == UIGestureRecognizerState.Began)
{
FireCommand();
}
}
public MvxLongPressGestureRecognizerBehaviour(UIView target)
{
var lp = new UILongPressGestureRecognizer(HandleGesture);
AddGestureRecognizer(target, lp);
}
}
and to bind
set.Bind(this.LongPress()).For(lp => lp.Command).To(c => c.DoTheStuffCommand);

How to pass parameters to a CodeActivity in a NativeActivity code sequence

I'm trying to get windows workflows working, and I've become a little stumped.
I've gotten a single workflow working, but now I am trying to do something a little more complex: start a workflow, where each activity itself contains a workflow. (Picture something like the main program starts the activities "Input, logic, and output", and then each of those have additional activities like "prompt user, get input, etc.")
I've had it working fine, with the example from here (http://msdn.microsoft.com/en-us/magazine/gg535667.aspx), when I am not passing any parameters from the main program to the activites. My question is, how exactly does the 'Variables' and 'metadata.SetVariablesCollection' work in the NativeActivity, and how to I get the parameters to the low level activities?
This is what I am currently trying:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Activities;
using System.Collections.ObjectModel;
using System.Activities.Statements;
namespace Project1
{
internal class MainProgram
{
internal static void Main(string[] args)
{
try
{
var act = new SimpleSequence();
act.Activities.Add((Activity)(new WriteSomeText()));
act.Activities.Add((Activity)(new WriteSomeText()));
act.Activities.Add((Activity)(new WriteSomeText()));
act.Variables.Add(new Variable<string> ("stringArg", "TEXT"));
WorkflowInvoker.Invoke(act);
}
catch (Exception ex)
{
System.Console.WriteLine("EXCEPTION: {0}", ex);
}
}
public class WriteSomeText : CodeActivity
{
[RequiredArgument]
public InArgument<string> stringArg { get; set; }
protected override void Execute(CodeActivityContext context)
{
string output = context.GetValue(stringArg);
System.Console.WriteLine(output);
}
}
public class SimpleSequence : NativeActivity
{
Collection<Activity> activities;
Collection<Variable> variables;
Variable<int> current = new Variable<int> { Default = 0 };
public Collection<Activity> Activities
{
get
{
if (this.activities == null)
this.activities = new Collection<Activity>();
return this.activities;
}
set
{
this.activities = value;
}
}
public Collection<Variable> Variables
{
get
{
if (this.variables == null)
this.variables = new Collection<Variable>();
return this.variables;
}
set
{
this.variables = value;
}
}
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
metadata.SetChildrenCollection(this.activities);
metadata.SetVariablesCollection(this.variables);
metadata.AddImplementationVariable(this.current);
}
protected override void Execute(NativeActivityContext context)
{
if (this.Activities.Count > 0)
context.ScheduleActivity(this.Activities[0], onChildComplete);
}
void onChildComplete(NativeActivityContext context, ActivityInstance completed)
{
int currentExecutingActivity = this.current.Get(context);
int next = currentExecutingActivity + 1;
if (next < this.Activities.Count)
{
context.ScheduleActivity(this.Activities[next], this.onChildComplete);
this.current.Set(context, next);
}
}
}
}
}
This ends up throwing the following exception:
EXCEPTION: System.Activities.InvalidWorkflowException: The following errors were encountered while processing the workflow tree:
'WriteSomeText': Value for a required activity argument 'stringArg' was not supplied.
'WriteSomeText': Value for a required activity argument 'stringArg' was not supplied.
'WriteSomeText': Value for a required activity argument 'stringArg' was not supplied.
at System.Activities.Validation.ActivityValidationServices.ThrowIfViolationsExist(IList`1 validationErrors)
at System.Activities.Hosting.WorkflowInstance.ValidateWorkflow(WorkflowInstanceExtensionManager extensionManager)
at System.Activities.Hosting.WorkflowInstance.RegisterExtensionManager(WorkflowInstanceExtensionManager extensionManager)
at System.Activities.WorkflowApplication.EnsureInitialized()
at System.Activities.WorkflowApplication.RunInstance(WorkflowApplication instance)
at System.Activities.WorkflowApplication.Invoke(Activity activity, IDictionary`2 inputs, WorkflowInstanceExtensionManager extensions, TimeSpan timeout)
at System.Activities.WorkflowInvoker.Invoke(Activity workflow, TimeSpan timeout, WorkflowInstanceExtensionManager extensions)
at System.Activities.WorkflowInvoker.Invoke(Activity workflow)
at Project1.MainProgram.Main(String[] args) in c:\users\user\documents\visual studio 2010\Projects\ModelingProject1\Project1\MainProgram.cs:line 25
I know, I only pass 1 parameter, but the exception still says that I am missing 3 parameters. I am missing something as to how to do this properly.
You're correctly declaring stringArg as an InArgument but you're not passing any value to it when calling it inside SimpleSequence.
You can pass something using the constructor, while constructing the all activity itself, like this:
public class WriteSomeText : CodeActivity
{
[RequiredArgument]
public InArgument<string> stringArg { get; set; }
public WriteSomeText(string stringArg)
{
this.stringArg = stringArg;
}
protected override void Execute(CodeActivityContext context
{
string output = context.GetValue(stringArg);
System.Console.WriteLine(output);
}
}
// Calling the activity like this:
internal static void Main(string[] args)
{
var act = new SimpleSequence()
{
Activities =
{
new WriteSomeText("hello"),
new WriteSomeText("world"),
new WriteSomeText("!")
}
};
WorkflowInvoker.Invoke(act);
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
Also notice that is a best practice to use the constructor to initialize collections:
public SimpleSequence()
{
activities = new Collection<Activity>();
variables = new Collection<Variable>();
}
This way is even more intuitive to initialize the activity:
var act = new SimpleSequence()
{
Activities =
{
new WriteSomeText("hello"),
new WriteSomeText("world"),
new WriteSomeText("!")
},
Variables =
{
new Variable<int>("myNewIntVar", 10),
// ....
}
};
EDIT:
There are a couple of other ways to approach the problem. This is your best friend while starting in the WF4 world.
Check WF\Basic\CustomActivities\Code-Bodied for a little push with this particular case.

Resources