Move Event types to the Matrix.Event namespace

This commit is contained in:
Gergely Polonkai 2016-03-07 09:44:06 +01:00 committed by Gergely Polonkai
parent 5f0b877db1
commit 70dfaff080
18 changed files with 497 additions and 479 deletions

13
.gitignore vendored
View File

@ -52,9 +52,10 @@ Makefile.in
/src/matrix-http-api.c /src/matrix-http-api.c
/src/matrix-http-client.c /src/matrix-http-client.c
/src/matrix-compacts.c /src/matrix-compacts.c
/src/matrix-event.c /src/matrix-event-base.c
/src/matrix-presence-event.c /src/matrix-event-presence.c
/src/matrix-room-event.c /src/matrix-event-room-base.c
/src/matrix-room-member-event.c /src/matrix-event-room-member.c
/src/matrix-state-event.c /src/matrix-event-state-base.c
/src/matrix-room-message-event.c /src/matrix-event-room-message.c
/src/namespace-info.c

View File

@ -16,18 +16,19 @@ lib_LTLIBRARIES = libmatrix-glib-0.0.la
# Vala source files # Vala source files
libmatrix_glib_0_0_la_VALA_SOURCES = \ libmatrix_glib_0_0_la_VALA_SOURCES = \
namespace-info.vala \
matrix-api.vala \ matrix-api.vala \
matrix-client.vala \ matrix-client.vala \
matrix-enums.vala \ matrix-enums.vala \
matrix-http-api.vala \ matrix-http-api.vala \
matrix-http-client.vala \ matrix-http-client.vala \
matrix-compacts.vala \ matrix-compacts.vala \
matrix-event.vala \ matrix-event-base.vala \
matrix-presence-event.vala \ matrix-event-room-base.vala \
matrix-state-event.vala \ matrix-event-state-base.vala \
matrix-room-event.vala \ matrix-event-presence.vala \
matrix-room-member-event.vala \ matrix-event-room-member.vala \
matrix-room-message-event.vala \ matrix-event-room-message.vala \
$(NULL) $(NULL)
AM_CPPFLAGS += \ AM_CPPFLAGS += \

View File

@ -357,7 +357,7 @@ public interface Matrix.API : GLib.Object {
string? topic, string? topic,
Matrix.RoomVisibility visibility, Matrix.RoomVisibility visibility,
Json.Node? creation_content, Json.Node? creation_content,
GLib.List<Matrix.StateEvent>? initial_state, GLib.List<Matrix.Event.State>? initial_state,
GLib.List<string>? invitees, GLib.List<string>? invitees,
GLib.List<Matrix.3PidCredential>? invite_3pids) GLib.List<Matrix.3PidCredential>? invite_3pids)
throws Matrix.Error; throws Matrix.Error;

View File

@ -47,7 +47,7 @@ public interface Matrix.Client : GLib.Object {
*/ */
[Signal (detailed=true)] [Signal (detailed=true)]
public virtual signal void public virtual signal void
@event(string? room_id, Json.Node raw_event, Matrix.Event matrix_event) @event(string? room_id, Json.Node raw_event, Matrix.Event.Base? matrix_event)
{} {}
/** /**
@ -61,7 +61,7 @@ public interface Matrix.Client : GLib.Object {
EventCallback(Matrix.Client client, EventCallback(Matrix.Client client,
string? room_id, string? room_id,
Json.Node raw_event, Json.Node raw_event,
Matrix.Event matrix_event); Matrix.Event.Base? matrix_event);
/** /**
* Authenticate with the Matrix.org server with a username and * Authenticate with the Matrix.org server with a username and
@ -144,9 +144,15 @@ public interface Matrix.Client : GLib.Object {
public void public void
incoming_event(string? room_id, incoming_event(string? room_id,
Json.Node raw_event, Json.Node raw_event,
Matrix.Event matrix_event) Matrix.Event.Base? matrix_event)
{ {
Quark equark = matrix_event.get_type().qname(); Quark equark;
if (matrix_event == null) {
equark = typeof(Matrix.Event.Base).qname();
} else {
equark = matrix_event.get_type().qname();
}
this.@event[equark.to_string()](room_id, raw_event, matrix_event); this.@event[equark.to_string()](room_id, raw_event, matrix_event);
} }
@ -161,7 +167,7 @@ public interface Matrix.Client : GLib.Object {
* *
* @param event_gtype the {@link GLib.Type} of a * @param event_gtype the {@link GLib.Type} of a
* {@link Matrix.Event} derivative * {@link Matrix.Event} derivative
* @param callback the allback function to connect * @param event_callback the allback function to connect
*/ */
public extern void public extern void
connect_event(GLib.Type event_gtype, connect_event(GLib.Type event_gtype,

View File

@ -15,6 +15,7 @@
* License along with matrix-glib-sdk. If not, see * License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>. * <http://www.gnu.org/licenses/>.
*/ */
namespace Matrix { namespace Matrix {
/** /**
* Abstract parent class for classes that can be saved to JSON. * Abstract parent class for classes that can be saved to JSON.

261
src/matrix-event-base.vala Normal file
View File

@ -0,0 +1,261 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
/**
* Base class for Matrix events.
*/
public abstract class Matrix.Event.Base : GLib.Object, GLib.Initable {
private Error? _construct_error = null;
private bool _inited = false;
private Json.Node? _json;
/**
* The type of the event. It should be namespaced similar to the
* Java package naming conventions,
* e.g. `com.example.subdomain.event.type`. It cannot be changed
* after object initialization.
*/
public string? event_type { get; construct; default = null; }
/**
* The event as a JSON node.
*/
public Json.Node? json {
get {
_json = new Json.Node(Json.NodeType.OBJECT);
_json.set_object(new Json.Object());
// Add the content node, as all event types must include it.
var content_root = new Json.Node(Json.NodeType.OBJECT);
var content_obj = new Json.Object();
content_root.set_object(content_obj);
_json.get_object().set_member("content", content_root);
try {
to_json(_json);
}
catch (Matrix.Error e) {
return null;
}
return _json;
}
construct {
if (value != null) {
try {
initialize_from_json(value);
} catch (Matrix.Error e) {}
}
}
}
public bool
init(GLib.Cancellable? cancellable = null)
throws Error, Matrix.Error
{
if (cancellable != null) {
throw new Matrix.Error.UNSUPPORTED(
"Cancellable initialization not supported");
}
if (_construct_error != null) {
throw _construct_error;
}
_inited = true;
return true;
}
private void
initialize_from_json(Json.Node json_data)
throws Matrix.Error
{
Json.Object root;
Json.Node node;
if (json_data.get_node_type() != Json.NodeType.OBJECT) {
throw new Matrix.Error.INVALID_FORMAT(
"The event is not valid");
}
root = json_data.get_object();
if ((node = root.get_member("type")) == null) {
throw new Matrix.Error.INCOMPLETE(
"Event type is not specified");
}
if ((_event_type != null)
&& (_event_type != node.get_string())) {
throw new Matrix.Error.INVALID_TYPE(
"Changing event type is not supported");
}
var evt_type = node.get_string();
if ((node = root.get_member("content")) == null) {
warning("content key is missing from the %s event", evt_type);
// As event type objects depend on having this node, lets
// add it now.
var content_node = new Json.Node(Json.NodeType.OBJECT);
content_node.set_object(new Json.Object());
root.set_member("content", content_node);
}
from_json(json_data);
_event_type = evt_type;
}
/**
* Subclasses should implement this function to initialize
* themselves from JSON data.
*/
public virtual void
from_json(Json.Node json_data)
throws Matrix.Error
{}
/**
* Subclasses should implement this to export their data to JSON.
*/
public virtual void
to_json(Json.Node json_data)
throws Matrix.Error
{
Json.Object root = json_data.get_object();
if (event_type != null) {
root.set_string_member("type", event_type);
}
}
public static Base?
new_from_json(owned string? event_type = null,
Json.Node? json_data = null)
throws Matrix.Error, GLib.Error
{
GLib.Type? event_gtype;
Base? ret = null;
if (event_type == null) {
if (json_data == null) {
throw new Matrix.Error.INCOMPLETE(
"Either event_type or json_data must be set!");
}
if (json_data.get_node_type() != Json.NodeType.OBJECT) {
throw new Matrix.Error.INVALID_FORMAT(
"Event is not a JSON object!");
}
Json.Node? node;
if ((node = json_data.get_object().get_member("type")) == null) {
throw new Matrix.Error.INCOMPLETE(
"event_type is null and JSON object doesn't contain type!");
}
event_type = node.get_string();
}
if ((event_gtype = get_handler(event_type)) == null) {
throw new Matrix.Error.INVALID_TYPE(
"No registered type for event type %s",
event_type);
}
ret = (Base)Object.new(event_gtype,
event_type : event_type,
json : json_data);
ret.init();
return ret;
}
}
namespace Matrix.Event {
private HashTable<string, TypeClass>? type_handlers = null;
/**
* Get the {@link GLib.Type} of the class that is registered to
* handle events with type @param event_type.
*
* @param event_type the event type to look up
* @return a {@link GLib.Type} or {@link Matrix.Event} if no
* handler is registered
*/
public static GLib.Type?
get_handler(string event_type)
{
unowned GLib.TypeClass? klass = null;
if ((type_handlers != null)
&& ((klass = type_handlers.get(event_type)) != null)) {
return klass.get_type();
}
if (Config.DEBUG) {
warning("No registered type for %s", event_type);
}
return null;
}
/**
* Registers @param event_type to be handled by the
* type @param event_gtype.
*
* @param event_type the type of the event
* @param event_gtype the {@link GLib.Type} of the events handler
*/
public static void
register_type(string event_type, GLib.Type event_gtype)
throws Matrix.Error
{
if (!event_gtype.is_a(typeof(Matrix.Event.Base))) {
throw new Matrix.Error.INVALID_TYPE(
"Invalid event type handler. It must be a subclass of MatrixEvent");
}
if (type_handlers == null) {
type_handlers = new HashTable<string, GLib.TypeClass>(
str_hash, str_equal);
}
type_handlers.replace(event_type, event_gtype.class_ref());
}
/**
* Unregister @param event_type.
*
* @param event_type the event type to remove
*/
public static void
unregister_type(string event_type)
{
if (type_handlers != null) {
type_handlers.remove(event_type);
}
}
}

View File

@ -21,10 +21,11 @@
* *
* The presence event class. * The presence event class.
*/ */
public class Matrix.PresenceEvent : Matrix.Event { public class Matrix.Event.Presence : Matrix.Event.Base {
public string? avatar_url { get; set; } public string? avatar_url { get; set; }
public string? display_name { get; set; } public string? display_name { get; set; }
public ulong? last_active_ago { get; set; } public ulong? last_active_ago { get; set; }
public string? user_id { get; set; default = null; }
public Matrix.Presence presence { public Matrix.Presence presence {
get; get;
set; set;
@ -39,7 +40,7 @@ public class Matrix.PresenceEvent : Matrix.Event {
Json.Node? node; Json.Node? node;
if ((node = content_root.get_member("user_id")) != null) { if ((node = content_root.get_member("user_id")) != null) {
_sender = node.get_string(); _user_id = node.get_string();
} else if (Config.DEBUG) { } else if (Config.DEBUG) {
warning("user_id is missing from the m.presence event"); warning("user_id is missing from the m.presence event");
} }
@ -86,17 +87,17 @@ public class Matrix.PresenceEvent : Matrix.Event {
"unkwnown presence cannot be added to a presence event"); "unkwnown presence cannot be added to a presence event");
} }
if (sender == null) { if (_user_id == null) {
throw new Matrix.Error.INCOMPLETE ( throw new Matrix.Error.INCOMPLETE (
"sender must be set for presence events!"); "sender must be set for presence events!");
} }
content_root = _json_object_node_ensure_field(json_data, content_root = json_data
"content", .get_object()
Json.NodeType.OBJECT) .get_member("content")
.get_object(); .get_object();
content_root.set_string_member("user_id", sender); content_root.set_string_member("user_id", _user_id);
if (last_active_ago != null) { if (last_active_ago != null) {
content_root.set_int_member("last_active_ago", last_active_ago); content_root.set_int_member("last_active_ago", last_active_ago);

View File

@ -0,0 +1,116 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
/**
* Abstract base class for room events.
*/
public abstract class Matrix.Event.Room : Matrix.Event.Base {
/**
* A globally unique event ID. Required.
*/
public string? event_id { get; set; default = null; }
/**
* The ID of the room associated with this event. Required.
*/
public string? room_id { get; set; default = null; }
/**
* The fully qualified Matrix ID of the user who sent the
* event. Required.
*/
public string? sender { get; set; default = null; }
/**
* The time, in milliseconds, that has elapsed since the event was
* sent. This is part of the unsigned event data.
*/
public ulong? age { get; set; default = null; }
/**
* The reason this event was redacted, if it was redacted.
*/
public string? redacted_because { get; set; default = null; }
/**
* The client-supplied transaction ID. This should only be set if
* the client being given the event is the same one which sent it.
*/
public string? transaction_id { get; set; default = null; }
protected override void
from_json(Json.Node json_data)
throws Matrix.Error
{
Json.Node? node;
var root = json_data.get_object();
if ((node = root.get_member("event_id")) != null) {
_event_id = node.get_string();
}
if ((node = root.get_member("room_id")) != null) {
_room_id = node.get_string();
}
if ((node = root.get_member("sender")) != null) {
_sender = node.get_string();
}
}
protected override void
to_json(Json.Node json_data)
throws Matrix.Error
{
var root_obj = json_data.get_object();
if (event_id != null) {
root_obj.set_string_member("event_id", event_id);
}
if (room_id != null) {
root_obj.set_string_member("room_id", room_id);
}
if (sender != null) {
root_obj.set_string_member("sender", sender);
}
var unsigned_obj = new Json.Object();
if (age != null) {
unsigned_obj.set_int_member("age", age);
}
if (redacted_because != null) {
unsigned_obj.set_string_member("redacted_because",
redacted_because);
}
if (transaction_id != null) {
unsigned_obj.set_string_member("transaction_id",
transaction_id);
}
if (unsigned_obj.get_size() > 0) {
var unsigned_node = new Json.Node(Json.NodeType.OBJECT);
unsigned_node.set_object(unsigned_obj);
root_obj.set_member("unsigned", unsigned_node);
}
}
}

View File

@ -21,8 +21,7 @@
* *
* The room membership event class. * The room membership event class.
*/ */
public class Matrix.RoomMemberEvent : Matrix.RoomEvent { public class Matrix.Event.RoomMember : Matrix.Event.State {
public string? state_key { get; set; }
public RoomMembership membership { public RoomMembership membership {
get; set; get; set;
default = RoomMembership.UNKNOWN; default = RoomMembership.UNKNOWN;
@ -38,18 +37,6 @@ public class Matrix.RoomMemberEvent : Matrix.RoomEvent {
Json.Object content_root = root.get_member("content").get_object(); Json.Object content_root = root.get_member("content").get_object();
Json.Node? node; Json.Node? node;
if ((node = root.get_member("state_key")) != null) {
_state_key = node.get_string();
} else if (Config.DEBUG) {
warning("state_key is missing from the m.room.member event");
}
if ((node = root.get_member("room_id")) != null) {
_room_id = node.get_string();
} else if (Config.DEBUG) {
warning("room_id is missing from the m.room.member event");
}
if ((node = content_root.get_member("membership")) != null) { if ((node = content_root.get_member("membership")) != null) {
Matrix.RoomMembership? mship = (Matrix.RoomMembership?)_g_enum_nick_to_value( Matrix.RoomMembership? mship = (Matrix.RoomMembership?)_g_enum_nick_to_value(
typeof(Matrix.RoomMembership), typeof(Matrix.RoomMembership),
@ -95,10 +82,6 @@ public class Matrix.RoomMemberEvent : Matrix.RoomEvent {
root.set_string_member("state_key", state_key); root.set_string_member("state_key", state_key);
if (room_id != null) {
root.set_string_member("room_id", room_id);
}
mship = _g_enum_value_to_nick(typeof(Matrix.RoomMembership), mship = _g_enum_value_to_nick(typeof(Matrix.RoomMembership),
membership); membership);

View File

@ -16,7 +16,7 @@
* <http://www.gnu.org/licenses/>. * <http://www.gnu.org/licenses/>.
*/ */
public class Matrix.RoomMessageEvent : Matrix.RoomEvent { public class Matrix.Event.RoomMessage : Matrix.Event.Room {
public string msg_type { get; set; } public string msg_type { get; set; }
public string body { get; set; } public string body { get; set; }

View File

@ -0,0 +1,57 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
public abstract class Matrix.Event.State : Matrix.Event.Base {
public string? state_key { get; set; default = null; }
public Json.Node? prev_content { get; set; default = null; }
protected override void
from_json(Json.Node json_data)
throws Matrix.Error
{
var root = json_data.get_object();
Json.Node? node;
if ((node = root.get_member("state_key")) != null) {
state_key = node.get_string();
}
if ((node = root.get_member("prev_content")) != null) {
_prev_content = node;
}
base.from_json(json_data);
}
protected override void
to_json(Json.Node json_node)
throws Matrix.Error
{
var root = json_node.get_object();
if (state_key != null) {
root.set_string_member("state_key", state_key);
}
if (prev_content != null) {
root.set_member("prev_content", prev_content);
}
base.to_json(json_node);
}
}

View File

@ -153,13 +153,13 @@ static void
matrix_event_types_ctor(void) matrix_event_types_ctor(void)
{ {
matrix_event_register_type("m.room.member", matrix_event_register_type("m.room.member",
MATRIX_TYPE_ROOM_MEMBER_EVENT, MATRIX_EVENT_TYPE_ROOM_MEMBER,
NULL); NULL);
matrix_event_register_type("m.presence", matrix_event_register_type("m.presence",
MATRIX_TYPE_PRESENCE_EVENT, MATRIX_EVENT_TYPE_PRESENCE,
NULL); NULL);
matrix_event_register_type("m.room.message", matrix_event_register_type("m.room.message",
MATRIX_TYPE_ROOM_MESSAGE_EVENT, MATRIX_EVENT_TYPE_ROOM_MESSAGE,
NULL); NULL);
} }
@ -172,11 +172,11 @@ matrix_client_connect_event(MatrixClient *client,
{ {
GClosure *closure; GClosure *closure;
GQuark equark; GQuark equark;
MatrixEventClass *event_class = MATRIX_EVENT_CLASS( MatrixEventBaseClass *event_class = MATRIX_EVENT_BASE_CLASS(
g_type_class_ref(event_gtype)); g_type_class_ref(event_gtype));
guint event_signal_id = g_signal_lookup("event", MATRIX_TYPE_CLIENT); guint event_signal_id = g_signal_lookup("event", MATRIX_TYPE_CLIENT);
if (!MATRIX_IS_EVENT_CLASS(event_class)) { if (!MATRIX_EVENT_IS_BASE_CLASS(event_class)) {
g_warning("Trying to connect to a type that is not derived from MatrixEvent"); g_warning("Trying to connect to a type that is not derived from MatrixEvent");
g_type_class_unref(event_class); g_type_class_unref(event_class);
@ -196,5 +196,4 @@ matrix_client_connect_event(MatrixClient *client,
g_signal_connect_closure_by_id(client, g_signal_connect_closure_by_id(client,
event_signal_id, equark, event_signal_id, equark,
closure, FALSE); closure, FALSE);
} }

View File

@ -1,341 +0,0 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
private HashTable<string, TypeClass>? event_type_handlers = null;
/**
* Base class for Matrix events.
*/
public class Matrix.Event : GLib.Object, GLib.Initable {
private Error? _construct_error = null;
private bool _inited = false;
private Json.Node? _json;
private Gee.HashMap<string, Json.Node> _custom_fields =
new Gee.HashMap<string, Json.Node>();
protected string? _sender = null;
protected string? _room_id = null;
/**
* The Matrix ID of the events sender.
*/
public string? sender {
get {
return _sender;
}
set {
_sender = value;
}
default = null;
}
/**
* The ID of the room this event is associated with.
*/
public string? room_id {
get {
return _room_id;
}
set {
_room_id = value;
}
default = null;
}
/**
* The type of the event.
*/
public string? event_type { get; construct; default = null; }
/**
* The timestamp of the event on the originating server.
*/
public ulong? origin_server_ts { get; set; default = null; }
/**
* The unsigned part of the event.
*/
public Matrix.UnsignedEventData unsigned_data {
get; set;
default = null;
}
/**
* The event as a JSON node.
*/
public Json.Node? json {
get {
if (_json == null) {
_json = new Json.Node(Json.NodeType.OBJECT);
_json.set_object(new Json.Object());
}
try {
to_json(_json);
}
catch (Matrix.Error e) {
return null;
}
return _json;
}
construct {
if (value != null) {
try {
initialize_from_json(value);
} catch (Matrix.Error e) {}
}
}
}
public bool
init(GLib.Cancellable? cancellable = null)
throws Error, Matrix.Error
{
if (cancellable != null) {
throw new Matrix.Error.UNSUPPORTED(
"Cancellable initialization not supported");
}
if (_construct_error != null) {
throw _construct_error;
}
_inited = true;
return true;
}
private void
initialize_from_json(Json.Node json_data)
throws Matrix.Error
{
Json.Object root;
Json.Node node;
if (json_data.get_node_type() != Json.NodeType.OBJECT) {
throw new Matrix.Error.INVALID_FORMAT(
"The event is not valid");
}
root = json_data.get_object();
if ((node = root.get_member("type")) == null) {
throw new Matrix.Error.INCOMPLETE(
"Event type is not specified");
}
if ((_event_type != null)
&& (_event_type != node.get_string())) {
throw new Matrix.Error.INVALID_TYPE(
"Changing event type is not supported");
}
from_json(json_data);
_event_type = node.get_string();
if ((node = root.get_member("origin_server_ts")) != null) {
_origin_server_ts = (ulong)node.get_int();
}
if ((node = root.get_member("sender")) != null) {
_sender = node.get_string();
}
if ((node = root.get_member("unsigned")) != null) {
_unsigned_data = new Matrix.UnsignedEventData.from_json(node);
}
}
/**
* Subclasses should implement this function to initialize
* themselves from JSON data.
*/
public virtual void
from_json(Json.Node json_data)
throws Matrix.Error
{}
/**
* Subclasses should implement this to export their data to JSON.
*/
public virtual void
to_json(Json.Node json_data)
throws Matrix.Error
{
Json.Object root = json_data.get_object();
foreach (var entry in _custom_fields.entries) {
root.set_member(entry.key, _json_node_deep_copy(entry.value));
}
if (event_type != null) {
root.set_string_member("type", event_type);
}
if (origin_server_ts != null) {
root.set_int_member("origin_server_ts", origin_server_ts);
}
if (sender != null) {
root.set_string_member("sender", sender);
}
if (unsigned_data != null) {
root.set_member("unsigned", unsigned_data.get_json_node());
}
}
public static Event?
new_from_json(owned string? event_type = null,
string? room_id = null,
Json.Node? json_data = null)
throws Matrix.Error, GLib.Error
{
GLib.Type event_gtype;
Event? ret = null;
if (event_type == null) {
if (json_data == null) {
throw new Matrix.Error.INCOMPLETE(
"Either event_type or json_data must be set!");
}
if (json_data.get_node_type() != Json.NodeType.OBJECT) {
throw new Matrix.Error.INVALID_FORMAT(
"Event is not a JSON object!");
}
Json.Node? node;
if ((node = json_data.get_object().get_member("type")) == null) {
throw new Matrix.Error.INCOMPLETE(
"event_type is null and JSON object doesn't contain type!");
}
event_type = node.get_string();
}
event_gtype = get_handler(event_type);
ret = (Event)Object.new(event_gtype,
event_type : event_type,
room_id : room_id,
json : json_data);
ret.init();
return ret;
}
/**
* Set a value for a custom field.
*/
public void
set_custom_field(string field_name, Json.Node value)
{
_custom_fields.set(field_name, value);
}
/**
* Get the value of a custom field.
*/
public Json.Node?
get_custom_field (string field_name)
{
return _custom_fields.get(field_name);
}
/**
* Delete a custom field.
*/
public void
delete_custom_field (string field_name)
{
_custom_fields.unset(field_name);
}
/**
* Get the {@link GLib.Type} of the class that is registered to
* handle events with type @param event_type.
*
* @param event_type the event type to look up
* @return a {@link GLib.Type} or {@link Matrix.Event} if no
* handler is registered
*/
public static GLib.Type
get_handler(string event_type)
{
unowned GLib.TypeClass? klass = null;
if ((event_type_handlers != null)
&& ((klass = event_type_handlers.get(event_type)) != null)) {
return klass.get_type();
}
if (Config.DEBUG) {
warning("Using Matrix.Event for %s", event_type);
}
return typeof(Matrix.Event);
}
/**
* Registers @param event_type to be handled by the
* type @param event_gtype.
*
* @param event_type the type of the event
* @param event_gtype the {@link GLib.Type} of the events handler
*/
public static void
register_type(string event_type, GLib.Type event_gtype)
throws Matrix.Error
{
if (!event_gtype.is_a(typeof(Matrix.Event))) {
throw new Matrix.Error.INVALID_TYPE(
"Invalid event type handler. It must be a subclass of MatrixEvent");
}
if (event_type_handlers == null) {
event_type_handlers = new HashTable<string, GLib.TypeClass>(
str_hash, str_equal);
}
event_type_handlers.replace(event_type, event_gtype.class_ref());
}
/**
* Unregister @param event_type.
*
* @param event_type the event type to remove
*/
public static void
unregister_type(string event_type)
{
if (event_type_handlers != null) {
event_type_handlers.remove(event_type);
}
}
}

View File

@ -809,7 +809,7 @@ public class Matrix.HTTPAPI : GLib.Object, Matrix.API {
string? topic, string? topic,
RoomVisibility visibility, RoomVisibility visibility,
Json.Node? creation_content, Json.Node? creation_content,
List<StateEvent>? initial_state, List<Matrix.Event.State>? initial_state,
List<string>? invitees, List<string>? invitees,
List<3PidCredential>? invite_3pids) List<3PidCredential>? invite_3pids)
throws Matrix.Error throws Matrix.Error

View File

@ -81,7 +81,7 @@ public class Matrix.HTTPClient : Matrix.HTTPAPI, Matrix.Client {
Json.Object root_obj; Json.Object root_obj;
Json.Node node; Json.Node node;
string event_type; string event_type;
Matrix.Event evt; Matrix.Event.Base? evt = null;
if (event_node.get_node_type() != Json.NodeType.OBJECT) { if (event_node.get_node_type() != Json.NodeType.OBJECT) {
if (Config.DEBUG) { if (Config.DEBUG) {
@ -104,19 +104,9 @@ public class Matrix.HTTPClient : Matrix.HTTPAPI, Matrix.Client {
event_type = node.get_string(); event_type = node.get_string();
try { try {
evt = Matrix.Event.new_from_json(event_type, room_id, event_node); evt = Matrix.Event.Base.new_from_json(event_type, event_node);
} catch (Matrix.Error e) {
if (Config.DEBUG) {
warning("Error during event creation: %s", e.message);
}
return;
} catch (GLib.Error e) { } catch (GLib.Error e) {
if (Config.DEBUG) { evt = null;
warning("Error during event creation: %s", e.message);
}
return;
} }
incoming_event(room_id, event_node, evt); incoming_event(room_id, event_node, evt);

View File

@ -1,58 +0,0 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
namespace Matrix {
public class StateEvent : Matrix.Event {
public string? state_key { get; set; default = null; }
public Json.Node? content { get; set; default = null; }
protected override void
from_json(Json.Node json_data)
throws Matrix.Error
{
var root = json_data.get_object();
Json.Node? node;
if ((node = root.get_member("state_key")) != null) {
state_key = node.get_string();
}
if ((node = root.get_member("content")) != null) {
content = node;
}
base.from_json(json_data);
}
protected override void
to_json(Json.Node json_node)
throws Matrix.Error
{
var root = json_node.get_object();
if (state_key != null) {
root.set_string_member("state_key", state_key);
}
if (content != null) {
root.set_member("content", content);
}
base.to_json(json_node);
}
}
}

View File

@ -16,7 +16,8 @@
* <http://www.gnu.org/licenses/>. * <http://www.gnu.org/licenses/>.
*/ */
/** [CCode (gir_namespace = "Matrix", gir_version = "0.10")]
* Abstract base class for room events. namespace Matrix {
*/ [CCode (gir_namespace = "Event", gir_version = "0.10")]
public abstract class Matrix.RoomEvent : Matrix.Event {} namespace Event {}
}

View File

@ -49,23 +49,23 @@ static void
cb_presence_event(MatrixClient *client, cb_presence_event(MatrixClient *client,
const gchar *room_id, const gchar *room_id,
JsonNode *raw_event, JsonNode *raw_event,
MatrixEvent *event, MatrixEventBase *event,
gpointer user_data) gpointer user_data)
{ {
g_printerr("Incoming presence event from %s!\n", g_printerr("Incoming presence event from %s!\n",
matrix_event_get_sender(event)); matrix_event_room_get_sender(MATRIX_EVENT_PRESENCE(event)));
} }
static void static void
cb_room_member_event(MatrixClient *client, cb_room_member_event(MatrixClient *client,
const gchar *room_id, const gchar *room_id,
JsonNode *raw_event, JsonNode *raw_event,
MatrixEvent *event, MatrixEventBase *event,
gpointer user_data) gpointer user_data)
{ {
g_printerr("Incoming room member event from %s in room %s (%s)\n", g_printerr("Incoming room member event from %s in room %s (%s)\n",
matrix_event_get_sender(event), matrix_event_room_get_sender(MATRIX_EVENT_ROOM(event)),
matrix_event_get_room_id(MATRIX_EVENT(event)), matrix_event_room_get_room_id(MATRIX_EVENT_ROOM(event)),
room_id); room_id);
} }
@ -73,13 +73,13 @@ static void
cb_room_message_event(MatrixClient *client, cb_room_message_event(MatrixClient *client,
const gchar *room_id, const gchar *room_id,
JsonNode *raw_event, JsonNode *raw_event,
MatrixEvent *event, MatrixEventBase *event,
gpointer user_data) gpointer user_data)
{ {
g_printf("Message from %s: %s\n", g_printf("Message from %s: %s\n",
matrix_event_get_sender(event), matrix_event_room_get_sender(MATRIX_EVENT_ROOM(event)),
matrix_room_message_event_get_body( matrix_event_room_message_get_body(
MATRIX_ROOM_MESSAGE_EVENT(event))); MATRIX_EVENT_ROOM_MESSAGE(event)));
} }
int int
@ -119,11 +119,11 @@ main(int argc, char *argv[])
"login-finished", "login-finished",
G_CALLBACK(login_finished), G_CALLBACK(login_finished),
loop); loop);
matrix_client_connect_event(client, MATRIX_TYPE_PRESENCE_EVENT, matrix_client_connect_event(client, MATRIX_EVENT_TYPE_PRESENCE,
cb_presence_event, NULL, NULL); cb_presence_event, NULL, NULL);
matrix_client_connect_event(client, MATRIX_TYPE_ROOM_MEMBER_EVENT, matrix_client_connect_event(client, MATRIX_EVENT_TYPE_ROOM_MEMBER,
cb_room_member_event, NULL, NULL); cb_room_member_event, NULL, NULL);
matrix_client_connect_event(client, MATRIX_TYPE_ROOM_MESSAGE_EVENT, matrix_client_connect_event(client, MATRIX_EVENT_TYPE_ROOM_MESSAGE,
cb_room_message_event, NULL, NULL); cb_room_message_event, NULL, NULL);
matrix_client_login_with_password(client, user, password, NULL); matrix_client_login_with_password(client, user, password, NULL);