A dart object has a ReceivePort member, to be able to get notified from C (C++) code (Not necessarily from dart thread). When the object is collected by the GC, the port should be closed too, but it does not seem to do it automatically. Therefore, I attached a C finalizer to the object like this. First thing I tried is, to send a closing message (in my case just Null) to the port with Dart_PostCObject_DL, but the port doesn't get notified. I assume, that's by specification, because the finalizer should not call any dart code.
So is there another way of closing the port, when the object is being collected?
Failed Method:
// Dart code
class SomeClass {
ReceivePort? port;
Pointer<Void> nativeData;
SomeClass () {
// Code to create native SomeClassData Object
CLibrary.library.attachFinalizer(this, nativeData);
}
void addCallback(void Function(data) callback) {
if (port == null) {
port = ReceivePort();
CLibrary.library.addCallback(port!.sendPort.nativePort, nativeData);
port.listen((message) {
if(message == null) {
port!.close();
return;
}
callback(message);
}
}
}
}
// C++ code
struct SomeClassData {
uint64_t port;
}
static void runFinalizer(void* isolate_callback_data, void* peer) {
std::cout << "Running finalizer" << std::endl;
SomeClassData* data = static_cast<SomeClassData*>(peer);
if(data->port != 0) {
Dart_CObject obj;
obj.type = Dart_CObject_kNull;
Dart_PostCObject_DL(data->port, obj); // Returns false <=> Unsuccessful
}
}
void attachFinalizer(Dart_Handle handle, void* someClassDataPointer) {
Dart_NewFinalizableHandle_DL(handle, someClassDataPointer, sizeof(SomeClassData), runFinalizer);
}
void addCallback(uint64_t port, void* someClassDataPointer) {
static_cast<SomeClassData*(someClassDataPointer)->port = port;
// Do something with port
}
Related
I need to call dart function do something and return data back to aqueduct controller. So, Can I call any dart function inside aqueduct response controller? If yes, how?
class NtmsApiController extends Controller {
#override
Future<RequestOrResponse> handle(Request request) async {
try {
if (request.path.remainingPath != null) {
_requestValue = request.path.remainingPath;
…
… can I go from here to dart function and get data back???? If yes, how?
UPDATE CODE:
I have global variable and it prints in null. Once the socket gets the data the void _printResponse(String _response) prints the data and from there I assign the data to global variable. But in Future handle data become null so I cannot return the as a response object. Any idea?
#override
Future<RequestOrResponse> handle(Request request) async {
_stopWatch = Stopwatch() //Global
..start();
_response = ""; // Global
if (request.path.remainingPath != null) {
final _requestValue = request.path.remainingPath;
await _getData(_requestValue);
}
print(_secureResponse); // It prints null, _secureResponse is Global variable
return Response.ok("$_secureResponse")
..contentType = ContentType.json;
}
//TODO: GET DATA FROM CSBINS
Future<Null> _getData(String _request) async {
await Socket.connect("192.168.22.120", 3000).then((Socket sock) {
_socket = sock;
_socket.write('$_request\r\n');
_socket.listen (dataHandler,
onError: errorHandler,
onDone: doneHandler,
cancelOnError: true);
}).catchError((AsyncError e) {
_response = "Server_Error";
});
}
void dataHandler(data) {
final List<int> byteArray = data;
_response = String.fromCharCodes(byteArray).trim();
}
void errorHandler(error, StackTrace trace) {
_response = "Server_Error";
}
void doneHandler() {
_socket.destroy();
}
void _printResponse(String _response) {
// prints succefully ***************************
print("$_response ... (${_stopWatch.elapsedMilliseconds} ms)");
_secureResponse = _response;
_stopWatch..stop();
if (_stopWatch.isRunning == false) {
_socket.flush();
_socket.close();
print("Socket Closed.");
}
}
I have very long collection - GList (huge amount of samples). For validation of every sample I am using g_list_foreach. The processing of the whole list lasts long. Sometimes it would be very useful to interrupt processing (via system signal SIGINT). Is there any way to interrupt foreach function?
It's trivial to implement something like g_list_foreach which would check a flag on each iteration, then you just need to install a signal handler to set the flag.
Here is the entire implementation of g_list_foreach:
void
g_list_foreach (GList *list,
GFunc func,
gpointer user_data)
{
while (list)
{
GList *next = list->next;
(*func) (list->data, user_data);
list = next;
}
}
How to install the handler will depend on how you want to structure your application, but if nothing else you could use a GOnce to install the handler, so something like:
static volatile gboolean my_flag = FALSE;
static void
handle_sigint(int id) {
my_flag = TRUE;
}
static gpointer
install_handler(gpointer data)
{
signal(SIGINT, handle_sigint);
return NULL;
}
/* Returns FALSE if interrupted, TRUE otherwise. */
gboolean
my_g_list_foreach (GList *list,
GFunc func,
gpointer user_data)
{
static GOnce handler_once = G_ONCE_INIT;
g_once(&handler_once, install_handler, NULL);
my_flag = FALSE;
while (list)
{
if (flag)
return FALSE;
GList *next = list->next;
(*func) (list->data, user_data);
list = next;
}
return TRUE;
}
I would like to parse binary file (from some old game) as on desktop as in browser.
So, I should use abstract class, which can read binary data from array of bytes:
abstract class BinData {
int readByte();
String readNullString(){
var buffer = new StringBuffer();
int char;
do {
char = readByte();
if (char == 0){
break;
}
buffer.writeCharCode(char);
} while(true);
return buffer.toString();
}
}
Now I can implement my parser. For example:
class Parser {
BinData _data;
void load(BinData data){
...
}
}
For desktop console application I use dart:io RandomAccessFile:
class FileBinData extends BinData {
RandomAccessFile _file;
FileBinData.from(RandomAccessFile file){
this._file = file;
}
int readByte(){
return this._file.readByteSync();
}
}
For web application I have to use dart:html FileReader. However, this class has only Future-based API, which isn't compatible with my interface:
class WebFileBinData extends BinData {
File _file;
int _position = 0;
WebFileBinData.from(File file){
this._file = file;
}
int readByte(){
Blob blob = _file.slice(_position, _position + 1);
FileReader reader = new FileReader();
var future = reader.onLoad.map((e)=>reader.result).first
.then((e) { ... });
reader.readAsArrayBuffer(blob);
...
}
}
How can I solve it?
Your readByte() should return Future<int> instead of int. You can return a Future from a function/method even when it doesn't do any async operation (return new Future.value(5);) but you can not return int (or any non-Future value) from a function which executes async operations, at least not when the value should be returned as result of the async operation.
You also need to ensure to connect all async calls.
Future<int> readByte(){
return reader.onLoad.map((e)=>reader.result).first
.then((e) {
...
return reader.readAsArrayBuffer(blob);
});
** readNullString
Future<String> readNullString() {
var buffer = new StringBuffer();
int char;
return Future.doWhile(() {
return readByte().then((char) {
if (char == 0) {
return false; // end doWhile
}
buffer.writeCharCode(char);
return true; // continue doWhile
});
}).then((_) => buffer.toString()); // return function result
}
I'm new to reactive programming using rxjava and after going through the simpler examples I'm now trying to figure out how to work with continuous streams. The problem I have with the example below is that the program doesn't terminate after I've taken the 3 elements. My assumption is that I somehow need to unsubscribe to my observable but I don't fully grasp how to terminate the while loop and make the program exit.
I've come across the following post RxJava -- Terminating Infinite Streams but I still can't figure out what I'm missing.
class MyTwitterDataProvider {
/*
This example is written in Groovy
Instance variables and constructor omitted
*/
public Observable<String> getTweets() {
BufferedReader reader = new BufferedReader(new InputStreamReader(getTwitterStream()))
Observable.create({ observer ->
executor.execute(new Runnable() {
def void run() {
String newLine
while ((newLine = reader.readLine()) != null) {
System.out.println("printing tweet: $newLine")
observer.onNext(newLine)
}
observer.onCompleted()
}
})
})
}
def InputStream getTwitterStream() {
// code omitted
}
public static void main (String [] args) {
MyTwitterDataProvider provider = new MyTwitterDataProvider()
Observable<String> myTweetsObservable = provider.getTweets().take(3)
Subscription myTweetSubscription = myTweetsObservable.subscribe({tweet-> println("client prints: $tweet")})
// myTweetSubscription.unsubscribe()
}
}
You must add a check in your loop to see if the observer is still subscribed:
while ((newLine = reader.readLine()) != null && !observer.isUnsubsribed()) {
System.out.println("printing tweet: $newLine")
observer.onNext(newLine)
}
I'm attempting to implement a BroadcastReceiver that will tell me when the network status has changed. I'll be using that to sync local data back to the main server when I get internet connection back after losing it.
As a start I was looking at this example: http://fizzylogic.nl/2013/08/17/xamarin-android-by-example-monitoring-the-network-status/
public class NetworkStatusMonitor
{
private NetworkState _state;
public NetworkStatusMonitor ()
{
}
public NetworkState State {
get {
UpdateNetworkStatus ();
return _state;
}
}
public void UpdateNetworkStatus() {
_state = NetworkState.Unknown;
// Retrieve the connectivity manager service
var connectivityManager = (ConnectivityManager)
Application.Context.GetSystemService (
Context.ConnectivityService);
// Check if the network is connected or connecting.
// This means that it will be available,
// or become available in a few seconds.
var activeNetworkInfo = connectivityManager.ActiveNetworkInfo;
if (activeNetworkInfo.IsConnectedOrConnecting) {
// Now that we know it's connected, determine if we're on WiFi or something else.
_state = activeNetworkInfo.Type == ConnectivityType.Wifi ?
NetworkState.ConnectedWifi : NetworkState.ConnectedData;
} else {
_state = NetworkState.Disconnected;
}
}
}
public enum NetworkState
{
Unknown,
ConnectedWifi,
ConnectedData,
Disconnected
}
Then my broadcast receiver looks like this:
[BroadcastReceiver()]
public class NetworkStatusBroadcastReceiver: BroadcastReceiver {
public event EventHandler ConnectionStatusChanged;
public override void OnReceive (Context context, Intent intent)
{
if (ConnectionStatusChanged != null)
ConnectionStatusChanged (this, EventArgs.Empty);
}
}
Now my question is... Where do I initialize this and where do I put the following Start() and Stop() methods?
public event EventHandler NetworkStatusChanged;
public void Start ()
{
if (_broadcastReceiver != null) {
throw new InvalidOperationException (
"Network status monitoring already active.");
}
// Create the broadcast receiver and bind the event handler
// so that the app gets updates of the network connectivity status
_broadcastReceiver = new NetworkStatusBroadcastReceiver ();
_broadcastReceiver.ConnectionStatusChanged += OnNetworkStatusChanged;
// Register the broadcast receiver
Application.Context.RegisterReceiver (_broadcastReceiver,
new IntentFilter (ConnectivityManager.ConnectivityAction));
}
void OnNetworkStatusChanged (object sender, EventArgs e)
{
var currentStatus = _state;
UpdateNetworkStatus ();
if (currentStatus != _state && NetworkStatusChanged != null) {
NetworkStatusChanged (this, EventArgs.Empty);
}
}
public void Stop() {
if (_broadcastReceiver == null) {
throw new InvalidOperationException (
"Network status monitoring not active.");
}
// Unregister the receiver so we no longer get updates.
Application.Context.UnregisterReceiver (_broadcastReceiver);
// Set the variable to nil, so that we know the receiver is no longer used.
_broadcastReceiver.ConnectionStatusChanged -= OnNetworkStatusChanged;
_broadcastReceiver = null;
}
Sorry for the probably silly question but still new to Xamarin and Android.
I think following link is helpful. I get the notification when the network status changes.
networkstatusbroadcastreceiver See Bradley's answer on the bottom of the page.