Skip to content

Commit

Permalink
Type System Simplified
Browse files Browse the repository at this point in the history
  • Loading branch information
AyushChothe committed Jun 8, 2022
1 parent 9f981c4 commit 00e6d66
Show file tree
Hide file tree
Showing 15 changed files with 164 additions and 102 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 0.0.3

- Typed Events Added (`PoloType` and `PoloTypeAdapter`)
- Rooms Feature Added
- Broadcast Feature Added

## 0.0.2+2

- Flutter Web Support Added
Expand Down
15 changes: 9 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,15 @@

- **Multi-Platform**
- `Android`, `IOS`, `Windows`, `Linux`, `macOS`, `Web`.
- **Easy to Use API**
- **Typed Events**
- Refer `PoloType` and `PoloTypeAdapter`.
- **Library Officially Available in Multiple Programming Languages**
- `Dart`, `TypeScript`.
- **Easy to Use API**

## 📖 Getting Started

### **Baic Chat App**
### **Basic Chat App**

- Server Code (Dart)

Expand All @@ -30,8 +33,8 @@
server.onClientConnect((client) {
print("Client(${client.id}) Connected!");
client.onEvent('message',
(message) => server.broadcastFrom(client.id, 'message', message));
client.onEvent<String>('message',
(message) => server.broadcastFrom<String>(client, 'message', message));
});
server.onClientDisconnect((client) {
Expand All @@ -53,7 +56,7 @@
print("Client Disconnected from Server");
});
client.onEvent('message', (message) {
client.onEvent<String>('message', (message) {
print("$message");
});
Expand All @@ -74,7 +77,7 @@ client.onDisconnect(() => {
console.log("Client Disconnected from Server");
});

client.onEvent("message", (message) => {
client.onEvent<string>("message", (message) => {
console.log(`${message}`);
});

Expand Down
49 changes: 20 additions & 29 deletions polo_client/example/polo_client_example.dart
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
import 'dart:io';

import 'package:polo_client/polo_client.dart';
import 'package:polo_client/src/polo_type.dart';

class UserType implements PoloType {
String? name;
int? age;
final String name;
final int age;

UserType({this.name, this.age});
UserType({required this.name, required this.age});

@override
UserType fromMap(Map<String, dynamic> map) {
factory UserType.fromMap(Map<String, dynamic> map) {
return UserType(name: map['name'], age: map['age']);
}

Expand All @@ -21,53 +18,47 @@ class UserType implements PoloType {
}

void main() async {
stdout.write("Enter Room to join: ");
// String room = stdin.readLineSync() ?? "root";

// Polo Client
PoloClient client = await Polo.connect("ws://127.0.0.1:3000/");

// PoloClient client =
// await Polo.connect("ws://polo-chat-server.herokuapp.com/");

// Future<void> getInput() async {
// stdin.listen((msg) {
// client.send('message', String.fromCharCodes(msg).trim());
// // client.send('messageToRoom',
// // {"room": room, "message": String.fromCharCodes(msg).trim()});
// });
// }
client.registerType(
PoloTypeAdapter<UserType>(
toMap: ((type) => type.toMap()),
fromMap: (map) => UserType.fromMap(map),
),
);

client.onConnect(() {
print("Client Connected to Server");

client.send('dynamic', "Ayush");
client.send('dynamic', 1);
client.send('dynamic', 3.14);
client.send('dynamic', true);
client.send('dynamic', [1, 2, 3]);
client.send('dynamic', null);
client.send('dynamic', {
"String": {"dynamic": true}
});
client.send<String>('message', "Hello from Client");
client.send<UserType>('userJoined', UserType(name: "Ayush", age: 22));
});

client.onDisconnect(() {
print("Client Disconnected from Server");
});

client.onEvent('dynamic', (dyn) {
stdout.writeln("Dynamic: $dyn : ${dyn.runtimeType}");
print("Dynamic: $dyn : ${dyn.runtimeType}");
});

client.onEvent<String>('message', (message) {
stdout.writeln("Message: $message : ${message.runtimeType}");
print("Message: $message : ${message.runtimeType}");
});

client.onEvent<UserType>('userJoined', (user) {
stdout.writeln("userJoined : ${user.toMap()} : ${user.runtimeType}");
}, converter: UserType());
print("userJoined : ${user.toMap()} : ${user.runtimeType}");
});

client.onDisconnect(() {
print("Client Disconnected from Server");
});

client.listen();
// getInput();
}
1 change: 1 addition & 0 deletions polo_client/lib/polo_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ library polo_client;
export 'src/polo_client_stub.dart'
if (dart.library.io) 'src/polo_io_client_helper.dart'
if (dart.library.html) 'src/polo_web_client_helper.dart';
export 'src/polo_type.dart';
8 changes: 6 additions & 2 deletions polo_client/lib/src/polo_client_stub.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ abstract class PoloClient {
}

/// Adds a Callback to an Event
void onEvent<T>(String event, void Function(T data) callback,
{PoloType? converter}) {
void onEvent<T>(String event, void Function(T data) callback) {
throw UnsupportedError("Platform is not Supported");
}

Expand All @@ -27,6 +26,11 @@ abstract class PoloClient {
throw UnsupportedError("Platform is not Supported");
}

/// Register a custom Object as a Type with `PoloTypeAdapter`
void registerType<T>(PoloTypeAdapter<T> type) {
throw UnsupportedError("Platform is not Supported");
}

/// Closes the connection to the `PoloServer`
Future<void> close() async {
throw UnsupportedError("Platform is not Supported");
Expand Down
33 changes: 23 additions & 10 deletions polo_client/lib/src/polo_io_client_base.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ part of 'polo_io_client_helper.dart';
class PoloClient implements stub.PoloClient {
final io.WebSocket _webSocket;
final Map<String, Function> _callbacks = {};

final Map<String, PoloTypeAdapter> _registeredTypes = {};
void Function() _onDisconnectCallback = () {};
void Function() _onConnectCallback = () {};

Expand All @@ -21,12 +21,13 @@ class PoloClient implements stub.PoloClient {

/// Adds a Callback to an Event
@override
void onEvent<T>(String event, void Function(T data) callback,
{PoloType? converter}) {
if (converter != null) {
assert(converter is T);
_callbacks[event] = (data) {
T typedData = converter.fromMap(data) as T;
void onEvent<T>(String event, void Function(T data) callback) {
String typeStr = T.toString();
if (_registeredTypes.containsKey(typeStr)) {
_callbacks[event] = (Map<String, dynamic> data) {
PoloTypeAdapter<T> typeAdapter =
_registeredTypes[typeStr]! as PoloTypeAdapter<T>;
T typedData = typeAdapter.fromMap(data);
callback(typedData);
};
} else {
Expand All @@ -46,14 +47,26 @@ class PoloClient implements stub.PoloClient {

/// Sends message to the Server from Client
@override
void send<T>(String event, dynamic data) {
if (data is PoloType) {
_webSocket.add(jsonEncode({'event': event, 'data': data.toMap()}));
void send<T>(String event, T data) {
String typeStr = T.toString();

if (_registeredTypes.containsKey(typeStr)) {
PoloTypeAdapter<T> typeAdapter =
_registeredTypes[typeStr]! as PoloTypeAdapter<T>;
_webSocket
.add(jsonEncode({'event': event, 'data': typeAdapter.toMap(data)}));
} else {
_webSocket.add(jsonEncode({'event': event, 'data': data}));
}
}

/// Register a Type to the `PoloClient`
@override
void registerType<T>(PoloTypeAdapter<T> type) {
final typeString = T.toString();
_registeredTypes[typeString] = type;
}

/// Closes the connection to the `PoloServer`
@override
Future<dynamic> close() {
Expand Down
12 changes: 11 additions & 1 deletion polo_client/lib/src/polo_type.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
/// Helps to build a `Polo` compatible Type
abstract class PoloType {
Map<String, dynamic> toMap() {
throw UnimplementedError();
}

PoloType fromMap(Map<String, dynamic> map) {
factory PoloType.fromMap(Map<String, dynamic> map) {
throw UnimplementedError();
}
}

/// Registers a Object or `PoloType` as a Type
class PoloTypeAdapter<T> {
PoloTypeAdapter({required this.toMap, required this.fromMap});

final Map<String, dynamic> Function(T type) toMap;

final T Function(Map<String, dynamic> map) fromMap;
}
34 changes: 25 additions & 9 deletions polo_client/lib/src/polo_web_client_base.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ part of 'polo_web_client_helper.dart';
class PoloClient implements stub.PoloClient {
final html.WebSocket _webSocket;
final Map<String, Function> _callbacks = {};

final Map<String, PoloTypeAdapter> _registeredTypes = {};
void Function() _onDisconnectCallback = () {};
void Function() _onConnectCallback = () {};

Expand All @@ -21,12 +21,16 @@ class PoloClient implements stub.PoloClient {

/// Adds a Callback to an Event
@override
void onEvent<T>(String event, void Function(T data) callback,
{PoloType? converter}) {
if (converter != null) {
assert(converter is T);
_callbacks[event] = (data) {
T typedData = converter.fromMap(data) as T;
void onEvent<T>(
String event,
void Function(T data) callback,
) {
String typeStr = T.toString();
if (_registeredTypes.containsKey(typeStr)) {
_callbacks[event] = (Map<String, dynamic> data) {
PoloTypeAdapter<T> typeAdapter =
_registeredTypes[typeStr]! as PoloTypeAdapter<T>;
T typedData = typeAdapter.fromMap(data);
callback(typedData);
};
} else {
Expand All @@ -47,13 +51,25 @@ class PoloClient implements stub.PoloClient {
/// Sends message to the Server from Client
@override
void send<T>(String event, T data) {
if (data is PoloType) {
_webSocket.sendString(jsonEncode({'event': event, 'data': data.toMap()}));
String typeStr = T.toString();

if (_registeredTypes.containsKey(typeStr)) {
PoloTypeAdapter<T> typeAdapter =
_registeredTypes[typeStr]! as PoloTypeAdapter<T>;
_webSocket.sendString(
jsonEncode({'event': event, 'data': typeAdapter.toMap(data)}));
} else {
_webSocket.sendString(jsonEncode({'event': event, 'data': data}));
}
}

/// Register a Type to the `PoloClient`
@override
void registerType<T>(PoloTypeAdapter<T> type) {
final typeString = T.toString();
_registeredTypes[typeString] = type;
}

/// Closes the connection to the `PoloServer`
@override
Future<dynamic> close() async {
Expand Down
2 changes: 1 addition & 1 deletion polo_client/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: polo_client
description: A WebSocket Library written in Pure Dart. Easy API for writing WebSocket based Apps or Games. Also Support for Flutter and Web.
repository: https://github.com/AyushChothe/polo
version: 0.0.2+2
version: 0.0.3
# homepage: https://www.example.com

environment:
Expand Down
50 changes: 18 additions & 32 deletions polo_server/example/polo_server_example.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import 'package:polo_server/polo_server.dart';
import 'package:polo_server/src/polo_type.dart';

class UserType implements PoloType {
String? name;
int? age;
final String name;
final int age;

UserType({this.name, this.age});
UserType({required this.name, required this.age});

@override
UserType fromMap(Map<String, dynamic> map) {
factory UserType.fromMap(Map<String, dynamic> map) {
return UserType(name: map['name'], age: map['age']);
}

Expand All @@ -21,10 +19,18 @@ class UserType implements PoloType {
void main() async {
// Manager
// Polo polo = await Polo.createManager();
// PoloServer server = polo.of('/chat');
// PoloServer server = polo.of('/');

// Direct Server
PoloServer server = await Polo.createServer();
PoloServer server = await Polo.createServer(address: "127.0.0.1", port: 3000);

// Register a Type
server.registerType<UserType>(
PoloTypeAdapter<UserType>(
toMap: (type) => type.toMap(),
fromMap: (map) => UserType.fromMap(map),
),
);

server.onClientConnect((client) {
print("Client(${client.id}) Connected!");
Expand All @@ -39,30 +45,10 @@ void main() async {
client.send('message', "Hello from Server");
});

client.onEvent<UserType>(
'userJoined',
(user) {
print("userJoined : ${user.toMap()} : ${user.runtimeType}");
client.send<UserType>('userJoined', user);
},
converter: UserType(),
);

// client.onEvent<String>('message',
// (message) => server.broadcastFrom(client, 'message', message));

// client.onEvent(
// 'messageToRoom',
// (payload) => server.broadcastToRoom(
// client, payload['room'], 'message', payload['message']));

// client.onEvent('joinRoom', (room) {
// client.joinRoom(room);
// });

// client.onEvent('leaveRoom', (room) {
// client.leaveRoom(room);
// });
client.onEvent<UserType>('userJoined', (user) {
print("userJoined : ${user.toMap()} : ${user.runtimeType}");
client.send<UserType>('userJoined', user);
});
});

server.onClientDisconnect((client) {
Expand Down
Loading

0 comments on commit 00e6d66

Please sign in to comment.