Reusing signal handlers? - vala

Is there a way in Vala to have multiple signal handlers perform the same code, while they have access to the local scope?
Defining a lambda using a delegate works, but requires a delegate definition and gives the warning "copying delegates is not supported":
delegate void ChangeHandler ();
void test () {
var answer = 42;
ChangeHandler handler = () => {
debug("size or position changed. answer: %i", answer);
};
size_changed.connect (handler);
position_changed.connect (handler);
}
As far as I know there is also no way to pass information to handlers? something like:
void test () {
var answer = 42;
size_changed.connect (handler, answer);
position_changed.connect (handler, answer);
}
void handler (answer) {
debug("size or position changed. answer: %i", answer);
}
I could do this, but this requires a lot of extra code, especially when there are many arguments.
void test () {
var answer = 42;
size_changed.connect (handler, answer);
position_changed.connect (() => handler(answer));
}
void handler (answer) {
debug("size or position changed. answer: %i", answer);
}
Is there a way to connect multiple signals to one anonymous function? Something like:
void test () {
var answer = 42;
multi_connect(size_changed, position_changed, () => {
debug("size or position changed. answer: %i", answer);
});
}

How about using this to pass data:
public class Test : GLib.Object {
public signal void sig_1 ();
public signal void sig_2 ();
private int answer = 42;
private void sig_handler (Test t) {
stdout.printf("sig_1 or sig_2 triggered. answer: %d\n", answer);
}
public static int main(string[] args) {
Test t1 = new Test();
t1.sig_1.connect(t1.sig_handler);
t1.sig_2.connect(t1.sig_handler);
t1.sig_1();
t1.sig_2();
return 0;
}
}
Maybe it is more readable with two classes:
public class SignalRaiser : GLib.Object {
public signal void sig_1 ();
public signal void sig_2 ();
}
public class SignalReceiver : GLib.Object {
private int answer = 42;
public void sig_handler (SignalRaiser sender) {
stdout.printf("sig_1 or sig_2 triggered. answer: %d\n", answer);
}
}
int main(string[] args) {
var raiser = new SignalRaiser();
var receiver = new SignalReceiver();
raiser.sig_1.connect(receiver.sig_handler);
raiser.sig_2.connect(receiver.sig_handler);
raiser.sig_1();
raiser.sig_2();
return 0;
}

Related

An object reference is required for the nonstatic field, method, or property into dotnet core [duplicate]

Consider:
namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//int[] val = { 0, 0};
int val;
if (textBox1.Text == "")
{
MessageBox.Show("Input any no");
}
else
{
val = Convert.ToInt32(textBox1.Text);
Thread ot1 = new Thread(new ParameterizedThreadStart(SumData));
ot1.Start(val);
}
}
private static void ReadData(object state)
{
System.Windows.Forms.Application.Run();
}
void setTextboxText(int result)
{
if (this.InvokeRequired)
{
this.Invoke(new IntDelegate(SetTextboxTextSafe), new object[] { result });
}
else
{
SetTextboxTextSafe(result);
}
}
void SetTextboxTextSafe(int result)
{
label1.Text = result.ToString();
}
private static void SumData(object state)
{
int result;
//int[] icount = (int[])state;
int icount = (int)state;
for (int i = icount; i > 0; i--)
{
result += i;
System.Threading.Thread.Sleep(1000);
}
setTextboxText(result);
}
delegate void IntDelegate(int result);
private void button2_Click(object sender, EventArgs e)
{
Application.Exit();
}
}
}
Why is this error occurring?
An object reference is required for the nonstatic field, method, or property 'WindowsApplication1.Form1.setTextboxText(int)
It looks like you are calling a non static member (a property or method, specifically setTextboxText) from a static method (specifically SumData). You will need to either:
Make the called member static also:
static void setTextboxText(int result)
{
// Write static logic for setTextboxText.
// This may require a static singleton instance of Form1.
}
Create an instance of Form1 within the calling method:
private static void SumData(object state)
{
int result = 0;
//int[] icount = (int[])state;
int icount = (int)state;
for (int i = icount; i > 0; i--)
{
result += i;
System.Threading.Thread.Sleep(1000);
}
Form1 frm1 = new Form1();
frm1.setTextboxText(result);
}
Passing in an instance of Form1 would be an option also.
Make the calling method a non-static instance method (of Form1):
private void SumData(object state)
{
int result = 0;
//int[] icount = (int[])state;
int icount = (int)state;
for (int i = icount; i > 0; i--)
{
result += i;
System.Threading.Thread.Sleep(1000);
}
setTextboxText(result);
}
More info about this error can be found on MSDN.
For this case, where you want to get a Control of a Form and are receiving this error, then I have a little bypass for you.
Go to your Program.cs and change
Application.Run(new Form1());
to
public static Form1 form1 = new Form1(); // Place this var out of the constructor
Application.Run(form1);
Now you can access a control with
Program.form1.<Your control>
Also: Don't forget to set your Control-Access-Level to Public.
And yes I know, this answer does not fit to the question caller, but it fits to googlers who have this specific issue with controls.
You start a thread which runs the static method SumData. However, SumData calls SetTextboxText which isn't static. Thus you need an instance of your form to call SetTextboxText.
Your method must be static
static void setTextboxText(int result)
{
if (this.InvokeRequired)
{
this.Invoke(new IntDelegate(SetTextboxTextSafe), new object[] { result });
}
else
{
SetTextboxTextSafe(result);
}
}
Credit to #COOLGAMETUBE for tipping me off to what ended up working for me. His idea was good but I had a problem when Application.SetCompatibleTextRenderingDefault was called after the form was already created. So with a little change, this is working for me:
static class Program
{
public static Form1 form1; // = new Form1(); // Place this var out of the constructor
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(form1 = new Form1());
}
}
I actually got this error because I was checking InnerHtml for some content that was generated dynamically - i.e. a control that is runat=server.
To solve this I had to remove the "static" keyword on my method, and it ran fine.
From my looking you give a null value to a textbox and return in a ToString() as it is a static method. You can replace it with Convert.ToString() that can enable null value.
Make the function static. This must solve your problem.
The essence, and solution, to your problem is this:
using System;
namespace myNameSpace
{
class Program
{
private void method()
{
Console.WriteLine("Hello World!");
}
static void Main(string[] args)
{
method();//<-- Compile Time error because an instantiation of the Program class doesnt exist
Program p = new Program();
p.method();//Now it works. (You could also make method() static to get it to work)
}
}
}

Instantiation of object in Vala generic

I want to create a new object of given type inside of generic in Vala language.
class MyClass <T> : GLib.Object
{
protected T data;
public MyClass ()
{
data = new T ();
}
}
I understand that this can't work, but what is the way to do something like that?
You are probably best instantiating it when calling the constructor for MyClass:
void main () {
new MyClass<Test> (new Test ());
new MyClass<Example> (new Example ());
}
class MyClass <T>
{
protected T data;
public MyClass (T data)
{
this.data = data;
}
}
class Test {}
class Example {}
Vala generics do not currently provide constraints. If you are going to pass in a dependency in this way you may want to consider using an interface type instead of a generic type.
Update
If you are wanting to implement a factory then an interface with a static method or function is probably best:
void main () {
var a = CommandFactory.get_command ("A");
var b = CommandFactory.get_command ("B");
a.run ();
b.run ();
}
namespace CommandFactory {
Command get_command (string criteria) {
Command result = null;
switch (criteria) {
case "A":
result = new CommandA ();
break;
case "B":
result = new CommandB ();
break;
default:
assert_not_reached ();
}
return result;
}
}
interface Command:Object {
public abstract void run ();
}
class CommandA:Object, Command {
void run () { print ("A\n"); }
}
class CommandB:Object, Command {
void run () { print ("B\n"); }
}
I assume by 'abstract fabric pattern' you mean 'abstract factory pattern'? You could try using GType introspection to then instantiate the Object, but it must be a GObject and you by pass Vala's static analysis checks:
void main () {
new MyClass<Example> (new Example ());
/* These will fail at runtime
new MyClass<string> ("this will fail at runtime");
new MyClass<ThisWillFailAtRuntime> (new ThisWillFailAtRuntime ());
*/
}
class MyClass <T>
{
protected T data;
public MyClass (T data)
{
assert (typeof(T).is_object());
this.data = Object.new (typeof(T));
}
}
class Example:Object {}
class ThisWillFailAtRuntime {}
Note that Object.new() is also a static method.
I'm not sure what you are trying to achieve, but you are probably better looking more closely at interfaces and favouring composition over inheritance in your object data model.

Some function to sleep in Vala

In Python there is a function called Time.Sleep () to pause the execution of a period of time, some alternative in Vala.
What I try to do is execute a While (True) but the content is executed in a certain period of time, for example 5 seconds.
Maybe have a look at the async example here:
// Build with: valac --pkg=gio-2.0 example.vala
public async void nap (uint interval, int priority = GLib.Priority.DEFAULT) {
GLib.Timeout.add (interval, () => {
nap.callback ();
return false;
}, priority);
yield;
}
private async void do_stuff () {
yield nap (1000);
}
private static int main (string[] args) {
GLib.MainLoop loop = new GLib.MainLoop ();
do_stuff.begin ((obj, async_res) => {
loop.quit ();
});
loop.run ();
return 0;
}
https://wiki.gnome.org/Projects/Vala/AsyncSamples

Override method in dart on fly (like JAVA)

Is there way to overriding method in Dart like JAVA, for example:
public class A {
public void handleLoad() {
}
}
And when overriding:
A a = new A() {
#Override
public void handleLoad() {
// do some code
}
};
No, Dart does not have anonymous classes. You have to create a class that extends A and instantiate it.
No but it much less useful in Dart because you can just reassign function:
typedef void PrintMsg(msg);
class Printer {
PrintMsg foo = (m) => print(m);
}
main() {
Printer p = new Printer()
..foo('Hello') // Hello
..foo = ((String msg) => print(msg.toUpperCase()))
..foo('Hello'); //HELLO
}
However you will need some extra boilerplate to access instance.
Use type Function:
class A {
final Function h
A(this.h);
void handleLoad(String loadResult) { h(loadResult); }
}
Or
class A {
final Function handleLoad;
A(this.handleLoad);
}
A a = new A((String loadResult){
//do smth.
});

a last in, first out (LIFO) abstract data type and data structure. Perhaps the most common use of stacks is to store

MyStack()
{
Vector<Integer> v=new Vector<Integer>(10,2);
}
void push(int n)
{
v.addElement(n);
}
void pop()
{
if(v.isEmpty())
System.out.println("Stack underflow!");
else
System.out.println(v.elementAt(0));
}
void display()
{
for(int i=0;i<v.size();i++)
System.out.print(v.elementAt(i) +" ");
}
}
class StackDemo
{
public static void main(String args[])
{
Scanner in=new Scanner(System.in);
MyStack s=new MyStack();
int option=0;
do
{
System.out.println("1: Push\n2:Pop\n3:Display\n4:Quit");
System.out.println("Enter your option: ");
option=in.nextInt();
switch(option)
{
case 1:
{
System.out.println("Enter an integer:");
int n=in.nextInt();
s.push(n);break;
}
case 2:s.pop();break;
case 3:s.display();break;
}
}
while(option!=4);
}
}
// throws an error: variable v not found. Any help would be much appreciated.Thanks.
It looks like v is being created locally in your constructor instead of as a member of your class.
Try defining v as a class member and then simply assign it in your constructor.
class MyStack {
Vector<Integer> v;
public MyStack() {
v = new Vector<Integer>(10,2);
}
}
Or just assign it when you define it:
class MyStack {
Vector<Integer> v = new Vector<Integer>(10,2);
}
Check out the Java tutorial on class members.

Resources