Can mousePressed be defined within a class? - processing

I am trying to create a class called InputManager to handle mouse events. This requires that mousePressed be contained within the InputManager class.
like so
class InputManager{
void mousePressed(){
print(hit);
}
}
problem is, that doesn't work. mousePressed() only seems to work when it's outside the class.
How can I get these functions nicely contained in a class?

Try this:
in main sketch:
InputManager im;
void setup() {
im = new InputManager(this);
registerMethod("mouseEvent", im);
}
in InputManager Class:
class InputManager {
void mousePressed(MouseEvent e) {
// mousepressed handling code here...
}
void mouseEvent(MouseEvent e) {
switch(e.getAction()) {
case (MouseEvent.PRESS) :
mousePressed();
break;
case (MouseEvent.CLICK) :
mouseClicked();
break;
// other mouse events cases here...
}
}
}
Once you registered InputManger mouseEvent in PApplet you don't need to call it and it will be called each loop at the end of draw().

Most certainly, but you are responsible for ensuring it gets called:
interface P5EventClass {
void mousePressed();
void mouseMoved();
// ...
}
class InputManager implements P5EventClass {
// we MUST implement mousePressed, and any other interface method
void mousePressed() {
// do things here
}
}
// we're going to hand off all events to things in this list
ArrayList<P5EventClass> eventlisteners = new ArrayList<P5EventClass>();
void setup() {
// bind at least one input manager, but maybe more later on.
eventlisteners.add(new InputManager());
}
void draw() {
// ...
}
void mousePressed() {
// instead of handling input globally, we let
// the event handling obejct(s) take care of it
for(P5EventClass p5ec: eventlisteners) {
p5ec.mousePressed();
}
}
I would personally make it a bit tighter by also passing the event variables explicitly, so "void mousePressed(int x, int y);" in the interface and then calling "p5ec.mousePressed(mouseX, mouseY);" in the sketch body, simply because relying on globals rather than local variables makes your code prone to concurrency bugs.

The easiest way to do so would be:
class InputManager{
void mousePressed(){
print(hit);
}
}
InputManager im = new InputManager();
void setup() {
// ...
}
void draw() {
// ...
}
void mousePressed() {
im.mousePressed();
}
This should solve any problems you were having with variable scoping in your class.
Note: In the class, it doesn't even have to be named mousePressed, you can name it anything you wish, as long as you call it inside of the main mousePressed method.

Related

Gluon Mobile Charm 5.0 Cannot Hide Layer

I have a loading gif for all backend requests. Prior to Charm 5.0.0, it worked fine in which the loading gif would show, backend would finish what it needed to, then the loading gif would be hidden. Now, the loading gif shows, but it doesn't hide.
addLayerFactory(LOADING_GIF, () -> new Layer() {
private final Node root;
private final double sizeX = getGlassPane().getWidth();
private final double sizeY = getGlassPane().getHeight();
{
ProgressIndicator loading = new ProgressIndicator();
loading.setRadius(50);
loading.setStyle("-fx-text-fill:white");
root = new StackPane(loading);
root.setStyle("-fx-background-color: rgba(0,0,0,0);");
getChildren().add(root);
this.setStyle("-fx-background-color:rgba(255,255,255,0.7)");
this.setShowTransitionFactory(v -> {
FadeInTransition ft = new FadeInTransition(v);
ft.setRate(2);
return ft;
});
}
#Override
public void show() {
this.setBackgroundFade(0.0);
super.show();
Layer pane = this;
Task<Integer> task = new Task<Integer>() {
#Override
protected Integer call() throws Exception {
int iterations = 0;
int max = DataService.readOutTime / 1000;
while (iterations <= max) {
Thread.sleep(1000);
iterations++;
}
Platform.runLater(new Runnable() {
#Override
public void run() {
if (pane.isVisible()) {
pane.setShowTransitionFactory(v -> {
FadeOutTransition ft = new FadeOutTransition(v);
ft.setRate(2);
return ft;
});
pane.hide();
MobileApplication.getInstance().showMessage("There was an error in sending your data.");
}
}
});
return iterations;
}
};
Thread thread = new Thread(task);
thread.start();
}
#Override
public void hide() {
this.setBackgroundFade(0.0);
super.hide();
}
#Override
public void layoutChildren() {
root.setVisible(isShowing());
if (!isShowing()) {
return;
}
root.resize(sizeX, sizeY);
resizeRelocate((getGlassPane().getWidth() - sizeX) / 2, (getGlassPane().getHeight() - sizeY) / 2, sizeX, sizeY);
}
});
I have a couple of utility methods that show and hide the loader:
public void showLoader() {
MobileApplication.getInstance().showLayer(App.LOADING_GIF);
}
public void hideLoader() {
MobileApplication.getInstance().hideLayer(App.LOADING_GIF);
}
Interestingly, the custom timeout I created (to hide the loader in case there is a stall in the backend) doesn't hide the layer either.
There is an issue with your code: you are overriding Layer::layoutChildren, but you are not calling super.layoutChildren().
If you check the JavaDoc:
Override this method to add the layout logic for your layer. Care should be taken to call this method in overriden methods for proper functioning of the Layer.
This means that you are getting rid of some important parts of the Layer control, such as animations, events and visibility control.
This should work:
#Override
public void layoutChildren() {
super.layoutChildren();
root.setVisible(isShowing());
if (!isShowing()) {
return;
}
root.resize(sizeX, sizeY);
resizeRelocate(getGlassPane().getWidth() - sizeX) / 2, getGlassPane().getHeight() - sizeY) / 2, sizeX, sizeY);
}
On a side note, for the hide transition, you should use setHideTransitionFactory.
So this is what I have done to solve this. From the Gluon Docs on the hide() method:
If this layer is showing, calling this method will hide it. If a hide transition is present, it is played before hiding the Layer. Care should be taken to call this only once LifecycleEvent.SHOWN has been fired.
Thus, I was realizing that the response from the backend was coming before the layer was fully shown. Thus, I modified the overridden hide() method as follows:
#Override
public void hide() {
if (this.isShowing()) {
this.setOnShown(e -> {
this.setBackgroundFade(0.0);
super.hide();
});
} else {
super.hide();
}
}
So if the layer is still in LifecycleEvent.SHOWING mode when being told to hide, make sure that it hides when it is shown. Otherwise it is already shown so hide it.

Moving comparisons out from the Update method: using delegates instead or another approach?

Let's go straight to an example. Let's say we have:
Update(){
if (value.Equals("circular")) moveGameObjectInACircularWay();
else if (value.Equals("linear")) moveGameObjectInALinearWay();
}
I think that is not very elegant solution. Unity needs to perform a comparison every frame. That does not sound very optimal to me. I'm just guessing it should be some other way to implement the same like:
Start () {
if (value.Equals("circular")) movement += moveGameObjectInACircularWay;
else if (value.Equals("linear")) movement += moveGameObjectInALinearWay;
}
Update () {
movement();
}
I guess the solution is related with delegates. That's why my proposed solution looks like delegates. I don't understand what delegates are well yet.
From MSDN "A delegate in C# is similar to a function pointer in C or C++. Using a delegate allows the programmer to encapsulate a reference to a method inside a delegate object." (https://msdn.microsoft.com/en-us/library/aa288459(v=vs.71).aspx) In short is a pointer to a method. What you want to do is the following:
using UnityEngine;
using System.Collections;
public delegate void MovementDelegate();
public class Movement : MonoBehaviour {
MovementDelegate movementFunction=null;
public string value = "linear";
void Start () {
if (value.Equals("circular")) movementFunction = moveGameObjectInACircularWay;
else if (value.Equals("linear")) movementFunction = moveGameObjectInALinearWay;
}
// Update is called once per frame
void Update()
{
if (movementFunction != null)
{
movementFunction();
}
}
void moveGameObjectInACircularWay()
{
Debug.Log("do circular movement here");
}
void moveGameObjectInALinearWay()
{
Debug.Log("do linear movement here");
}
}
The functions you declare must have the same signature as the delegate signature. If you want to add parameters to it, ex. an int, decalre your delegate as
public delegate void MovementDelegate(int speed);
and your implementation functions as
void moveGameObjectInACircularWay(int speed)
void moveGameObjectInALinearWay(int speed)
and change the call to
movementFunction(yourIntHere)
UPDATED!: Thanks to Joe Blow suggestion here is another solution:
public class Movement : MonoBehaviour
{
Action<int> movementFunction = null;
public string value = "linear";
void Start()
{
if (value.Equals("circular")) movementFunction = moveGameObjectInACircularWay;
else if (value.Equals("linear")) movementFunction = moveGameObjectInALinearWay;
}
// Update is called once per frame
void Update()
{
if (movementFunction != null)
{
movementFunction(2);
}
}
void moveGameObjectInACircularWay(int speed)
{
Debug.Log("do circular movement here "+ speed);
}
void moveGameObjectInALinearWay(int speed)
{
Debug.Log("do linear movement here " + speed);
}
}
My favorite answer has been written by Joe Blow in the comments:
Unity is components based. We better switch to Component-Based Thinking instead working with delegates.
So make two (or more) different scripts, and put those on the game object in question. Then, turn on and off these components as you wish.
So we would have to scripts added to our game object: MoveGameObjectInACircularWay.cs and MoveGameObjectInALinearWay.cs. Then a MainGameObjectScript.cs also added to our game object with the following code:
void Start () {
GetComponent()<MoveGameObjectInACircularWay>.active = true;
GetComponent()<MoveGameObjectInALinearWay>.active = false;
}

How would I change the colour of an object using 'OnMouseEnter'?

The script used to be:
function OnMouseEnter()
{
renderer.material.color = Color.grey;
}
But using that is now obsolete after an update and I have no idea what the current syntax is or how one would go about finding it out. I've searched everywhere and couldn't find an answer.
Since Unity 4.6 there is a new way of handling input events. One have to use interfaces from UnityEngine.EventSystems namespace. Look at this example:
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems; // dont forget this
public class SomeController : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerClickHandler
{
private bool hovered = false;
// from IPointerEnterHandler
public void OnPointerEnter(PointerEventData eventData)
{
hovered = true;
}
// from IPointerExitHandler
public void OnPointerExit(PointerEventData eventData)
{
hovered = false;
}
// from IPointerClickHandler
public void OnPointerClick(PointerEventData eventData)
{
// send some event
}
}
Still, you have to add collider component to your object.

C# like events in D programming language

I recently finished a 6-month internship at a company that uses C# for the most part of their programming. During this time I first used and got accustomed to the C# way of doing events. Like shown below:
acc.AccountBalanceLow += new AccountBalanceDelegate(atm.AccountToLow);
acc.AccountBalanceLow +=new AccountBalanceDelegate(atm.AccountToLowAgain);
Does D support such constructs? I'd imagine one could be created by the user by using operator overloading, but I'm not entirely sure. If it's not possible what would then be a common excepted way of doing it then?
The equivalent construct in D is to use Signals and Slots. This is a different means of implementing the Observer Pattern, which is effectively what a C# event does.
D (and C++) use an analogous pattern called signals and slots.
If you're feeling the need to use the C# style-events instead of signals and slots, they're extremely simple to implement:
module fluidity.core.event;
class Event {
alias void delegate(EventArgs) handler_t;
handler_t[] handlers;
Object owner;
this() {}
this(Object o) { owner = o; }
void attach(handler_t handler) {
if (handler)
handlers ~= handler;
}
void detach(handler_t handler) {
int i = -1;
foreach (j, h; handlers)
{
if (h is handler)
{
i = j;
break;
}
}
if (i > -1)
handlers = handlers[0..i] ~ handlers[i+1..$];
}
void raise() { raise(new EventArgs(owner)); }
void raise(EventArgs e) {
// call all handlers
foreach (handler; handlers)
{
if (handler)
handler(e);
}
}
void opAddAssign(handler_t handler) {
attach(handler);
}
void opSubAssign(handler_t handler) {
detach(handler);
}
}
class EventArgs {
Object source;
bool handled;
void handle() { handled = true; }
this() {}
this(Object s) {
source = s;
}
}
Here is an example of c# style events using signals, slots, and a templates:
events.d:
import std.signals;
class Event(T...){
mixin Signal!(T);
void broadcast(T args){
emit(args);
}
void opAddAssign(slot_t slot){
connect(slot);
}
void opSubAssign(slot_t slot) {
disconnect(slot);
}
}
declaration:
public Event!(int) onSomeEventOfInt;
public Event!(string, int) onSomeEventOfStringAndInt;
instantiation:
this.onSomeEventOfInt = new Event!(int)();
this.onSomeEventOfStringAndInt = new Event!(string, int)();
fire event:
int i = 4;
string str = "hello";
this.onSomeEventOfInt.broadcast(i);
this.onSomeEventOfStringAndInt.broadcast(str, 4);
observer registration:
obj1.onSomeEventOfInt += &handleEventOfInt
obj1.onSomeEventOfStringAndInt += &handleEventOfStringAndInt
void handleEventOfInt(int g)
{ /*do something */ }
void handleEventOfStringAndInt(string str, int g)
{ /*do something */ }
Check out DFL's event system. It works EXACTLY the same way as C# .NET.
DFL Event Example
Download DFL, grab the events module and use it the way you like. I modified it to use variadic template arguments. This gives maximum flexibility.
http://www.dprogramming.com/dfl098.zip

Proper way of raising events from C++/CLI?

I was wondering what's the proper way of raising events from C++/CLI. In C# one should first make a copy of the handler, check if it's not null, and then call it. Is there a similar practice for C++/CLI?
This isn't the whole story! You don't usually have to worry about null event handlers in C++/CLI. The code for these checks is generated for you. Consider the following trivial C++/CLI class.
public ref class MyClass
{
public:
event System::EventHandler ^ MyEvent;
};
If you compile this class, and disassemble it using Reflector, you get the following c# code.
public class MyClass
{
// Fields
private EventHandler <backing_store>MyEvent;
// Events
public event EventHandler MyEvent
{
[MethodImpl(MethodImplOptions.Synchronized)] add
{
this.<backing_store>MyEvent = (EventHandler) Delegate.Combine(this.<backing_store>MyEvent, value);
}
[MethodImpl(MethodImplOptions.Synchronized)] remove
{
this.<backing_store>MyEvent = (EventHandler) Delegate.Remove(this.<backing_store>MyEvent, value);
}
raise
{
EventHandler <tmp> = null;
<tmp> = this.<backing_store>MyEvent;
if (<tmp> != null)
{
<tmp>(value0, value1);
}
}
}
}
The usual checks are being done in the raise method. Unless you really want custom behavior, you should feel comfortable declaring your event as in the above class, and raising it without fear of a null handler.
C++/CLI allows you to override raise in custom event handlers so you don't have to test for null or copy when raising the event. Of course, inside your custom raise you still have to do this.
Example, adapted from the MSDN for correctness:
public delegate void f(int);
public ref struct E {
f ^ _E;
public:
void handler(int i) {
System::Console::WriteLine(i);
}
E() {
_E = nullptr;
}
event f^ Event {
void add(f ^ d) {
_E += d;
}
void remove(f ^ d) {
_E -= d;
}
void raise(int i) {
f^ tmp = _E;
if (tmp) {
tmp->Invoke(i);
}
}
}
static void Go() {
E^ pE = gcnew E;
pE->Event += gcnew f(pE, &E::handler);
pE->Event(17);
}
};
int main() {
E::Go();
}
If your issue is that raise isn't private, then explicitly implement it like the docs say:
http://msdn.microsoft.com/en-us/library/5f3csfsa.aspx
In summary:
If you just use the event keyword, you create a "trivial" event. The compiler generates add/remove/raise and the delegate member for you. The generated raise function (as the docs say) checks for nullptr. Trivial events are documented here:
http://msdn.microsoft.com/en-us/library/4b612y2s.aspx
If you want "more control", for example to make raise private, then you have to explicitly implement the members as shown in the link. You must explicitly declare a data member for the delegate type. Then you use the event keyword to declare the event-related members, as in the Microsoft example:
// event keyword introduces the scope wherein I'm defining the required methods
// "f" is my delegate type
// "Event" is the unrealistic name of the event itself
event f^ Event
{
// add is public (because the event block is public)
// "_E" is the private delegate data member of type "f"
void add(f ^ d) { _E += d; }
// making remove private
private:
void remove(f ^ d) { _E -= d; }
// making raise protected
protected:
void raise(int i)
{
// check for nullptr
if (_E)
{
_E->Invoke(i);
}
}
}// end event block
Wordy, but there it is.
-reilly.

Resources