Working Canon PIXMA G3010/G3110 @ macOS

The only way to make this work is by using it vía network, forget about USB. Also, it only works as a printer, not as a scanner, blame Canon for not even implementing proper Bonjour support as a multifunctional printer. To make it work:

  • Download the drivers for the Canon PIXMA G3000 (it says 3200 but it’s the one for the 3000)
  • Download the Canon Android APP and setup the printer to connect to your network.
  • Install the PIXMA G3000 drivers and setup the printer as a network printer.

Done. It shows up as a regular printer, and you can print from it (it takes a little bit longer than printing from Windows), but it’s just a regular printer. The Android App might include some PPD files and/or drivers to really make it work, but who knows? I made sure to ask someone else to do the wireless setup for me so that I didn’t have to agree to any of the usually insane Terms & Conditions. This process might work for Linux-based systems but I do not use any of them at work, and I do not use printers at home.

Advertisements

More about Unions in Vala

In a previous post I speculated about adding tagged unions to Vala. Let’s do that again.

In order to support the C usecase, Vala would need to include 2 types of tagged unions, a legacy one, and an idiomatic one. The legacy should look like the C version of a tagged union:

struct tagged {
    short tag;
    union variants {
        string text;
        int num;
    }
} tagged;

This is needed to bind the C libs out there. The type of the tag should be something that can be easily compared IMO (numeric datatypes, C enums, and string). The binding would then look like this:

[CCode (cname = "tagged", union_tag_field = "tag" union_tag_type = "short" union_field = "variants")]
union Tagged {
    [CCode (cname = "text", union_tag_id = "1")]
    TEXT(string),
    [CCode (cname = "num", union_tag_id = "2")]
    NUM(int)
}

The idiomatic ones, however, would actually look like a Rust struct, so if we declare:

public union OrderStatus {
	ACCEPTED,
	CANCELLED {string reason, string cancelled_by},
	REJECTED {string reason},
	COMPLETED {DateTime completed_at},
	ON_HOLD {string reason, Datetime until}
}

We should get:

enum OrderStatusTag {
	ACCEPTED,
	CANCELLED,
	REJECTED,
	COMPLETED,
	ON_HOLD
} OrderStatusTag

union order_status {
    struct accepted {OrderStatusTag tag};
    struct cancelled {OrderStatusTag tag; string reason, string cancelled_by};
    struct rejected {OrderStatusTag tag; string reason};
    struct completed {OrderStatusTag tag; GDateTime completed_at};
    struct on_hold {OrderStatusTag tag; string reason; GDatetime until};
} OrderStatus;

Fun things to support: GVariant variant types (unboxing, serialization, etc.), GValue, JSON representations.

Converting Array fields from PostgreSQL in jOOQ

There’s currently a “bug” (not really a bug, but it works for me in MySQL) that prevents jOOQ from reusing a forcedType when it appears as an array instead of a single value. I have a workaround for this: a forcedType for the array field, and binding it by field name. To facilitate the creation of an Array Converter, just subclass this and pass the right converter in the super() call:

Unions in Vala

I’ve started to use Kotlin professionally, and keeping an eye on Rust. Both offer a lot of niceties that I wish we could adapt for Vala, but there’s one that keeps popping up my mind everytime: pattern matching.

The simplest pattern matching we have is C unions, and a lot of c-libs use them. Unfortunately, the current handling of unions in Vala is a disgrace, and there’s no alternative for it. But I believe we can import some syntax from both Kotlin and Rust. Here is my proposal of how should unions work in Vala:

//Opening a bracket defines an "anonymous struct"
public union OrderStatus {
	ACCEPTED,
	CANCELLED {string reason, string cancelled_by},
	REJECTED {string reason},
	COMPLETED {DateTime completed_at}
	ON_HOLD {string reason, Datetime until}
}

match (order.status) {
	ACCEPTED -> info("Cool!");
	CANCELLED -> debug(@"Not okay, it was cancelled because of $(it.reason) by $(it.cancelled_by)");
	REJECTED as that -> info (@"Rejected: $that.reason");
	default -> error("What is this?? There's no implicit \"it\" here because it's a catch-all!")
}

public union NestedUnion {
	SIMPLE,
	union COMPLEX {
		SOFT,
		HARD{string reason}
	}
}

//The additional field belongs to the wrapping struct

public union ComplexUnion {
	FIRST,
	SECOND,
	THIRD {string reason};
	//parent field, children cannot have a field with the same name
	uint32 timestamp;
}

//Maybe this is not a good idea

public union VeryComplex {
	FIRST {
		override void run() {
			log("Uy!")
		}
	},
	SECOND {
		override void run() {
			log("Ouch!");
		}
	},
	THIRD {
		override void run() {
			log("Ay!");
		}
		override void do() {
			debug ("Yay!");
		}
	}
	
	//They are all required to implement it!
	abstract void run();
	
	//Optionally overriden
	virtual void do() {
		
	}
	//Can't touch this
	public void execute() {
	}
}

//In this case, they reuse existing datatypes

public union ExternalUnion {
	STRING(string),
	NUMBER(uint64),
	THINGY(GLib.Object)
}

public void method () {
	var order = new Order(OrderStatus.ON_HOLD("reason", DateTime.now()));
	var other_order = new Order(OrderStatus.CANCELLED(cancelled_by = "desiderantes", reason = "who knows!")); 
	
	var nested = NestedUnion.COMPLEX.HARD(reason = "no reason at all");
	//'match' can return a value, but all branches should return the same type
	//this 'match' in particular is exhaustive, so no default needed, but if you return a value from 'match', you have to either
	//cover all cases or have a default branch
	
	NestedUnion another_nested = get_from_network();
	var reason = match (another_nested) {
		SIMPLE -> "Just because";
		COMPLEX -> match (it) {
			SOFT -> "Really easy";
			//if not renamed, then you'll lose access to the it from outer context, as it'll be shadowed
			HARD as that -> that.reason;
		}
	}
	
	//This errors
	var complex = ComplexUnion(123456789);
	var complex = ComplexUnion();
	var complex = ComplexUnion.FIRST();

	//This should work
	var complex = ComplexUnion.THIRD(123456789, "I can");
	var complex = ComplexUnion.THIRD(reason = "Just because", timestamp = 321654987);
	
	
	match (complex) {
		//properties from the parent are only accessible from the parent reference, no implicit parent var
		FIRST -> debug(@"$(complex.timestamp)");
		SECOND -> debug ("Oops");
		THIRD -> debug @("$(complex.timestamp) by $(it.reason)");
	}
	
	var external = ExternalUnion.STRING("this string is required");
}

The internal structure (C-wise) of my proposed tagged union is not anything new, it has been done a lot before in C land (here is an explanation from the Rust viewpoint)

Tip: Emitting the notify signal in Vala

I needed a way to emit the notify signal of one of my objects from another place, and Vala didn’t show me a straightforward way to do it. If you need it for some reason, here’s a code snippet showing you how:

using GLib;

public class TestClass : GLib.Object {
	public string test1 {get;set;default = "test1";}
	//Ths one won't emit on assignment
	[CCode (notify = false)]
	public string test2 {get;set;default = "test2";}

	public static void main (string[] args) {
		var test = new TestClass ();
		test.notify["test1"].connect (() => GLib.print ("test1 notification\n"));
		test.notify["test2"].connect (() => GLib.print ("test2 notification\n"));
		test.test1 = "Ahoy";
		test.test2 = "Újale";
		test.test2 = "Ajúa";
		ParamSpec pspec = ((ObjectClass) typeof (TestClass).class_ref ()).find_property ("test2");
		GLib.print ("First try, will not work %s\n", pspec.name);
		test.notify(pspec);
		GLib.print ("second one, this is how it works");
		test.notify["test2"] (pspec);
		return;
	}
}

Replay Edits

Being in the zone is amazing: your productivity skyrockets and the code just flows. Then somebody micromanages talks to you, the boss starts to scream discuss things on the phone, or it’s lunch time and this company won’t give back any minute you waste before starting to eat. Since this hapenned to me at least once, I’ve been looking for a simple way to get back my productivity when I resume my job. I’ve found that the best way for me is just doing insane amounts of Ctrl+Z and Ctrl+Shift+Z/Ctrl+Y to see what I did and where did I did it. But this is a tiresome activity, the kind that I expect to be automated. So why not add a simple option in your text editor, a nice Replay Edits that’ll just play in real time edits from last saved state to current state? I want this, and if you know something like this, PLEASE tell me, I’m all ears.

Abandoned Vala Projects

There was a time when Vala was really popular, and a plethora of Vala apps spawned. A lot of them are dead right now, so since i don’t have time to revive any of them, i’ll publish this list of interesting projects in case someone is interested in bringing back one of them: