lgcre 0.0.7 lgcre: ^0.0.7 copied to clipboard
Local Graph Context-based Recommende Engine. This is a library to build peronalized POI (point of intereset) recommender engines on the device. Specifiy a graph of related tags or categories, and whic [...]
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:collection';
import 'dart:convert';
import 'package:flutter/services.dart';
import 'package:lgcre/lgcre.dart';
import 'package:isolate_handler/isolate_handler.dart';
/** This example uses the isolate_handler package to show how to execute the plugin commands
in an isolate thread. The reason to use this package is because the plugin uses platform native code,
and the method to invoke such code, the invokeMethod API, does not work on common isolate threads
executed through the compute API **/
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
void useLGCRE(Map<String, dynamic> context) async {
final messenger = HandledIsolate.initialize(context);
messenger.listen((msg) async {
String status;
// Platform messages may fail, so we use a try/catch PlatformException.
try {
status="WAITING";
// LGCRE: INITIALIZATION
Map<String,String> options = {
'lgcre.licenseid' : '<license-id>',
'lgcre.clientid' : '<client-id>',
'lgcre.loglevel' : 'fine',
'lgcre.maxmem' : '64'
};
await Lgcre.init(options);
// LGCRE: RESETTING THE DATA
await Lgcre.reset();
// ADDING DATA
// Each data key (pois, categories, link_categories,
// etc...) can be null if no data needs to be added from that type. In
// this example we add data for all types just as an example
Map<String,dynamic> data = new Map<String, dynamic>();
// Add pois to the recommender. For instance, when we know the person has
// visited one poi and we want to represent this by means of a link
// between the person and the poi (see below)
data['pois'] = ["poi1", "poi2", "poi3", "poi4"];
// Add categories to the recommender. For instance, because we know the
// person is interested in a particular category or because we know that a poi
// the user has visited, has a category (see below)
data['categories'] = ["cat1", "cat2", "cat3", "cat4"];
// Add links between categories to the recommender. For instance, when
// we know that two categories are related. Both categories must have been
// previously added before through the categories field, either in this
// call or in a previous call to 'addData' (see above).
data['links_categories'] = [
{'category1' : 'cat1',
'category2' : 'cat2'},
{'category1' : 'cat1',
'category2' : 'cat3'},
{'category1' : 'cat2',
'category2' : 'cat4'},
];
// Add links between pois and categories to the recommender. When we know
// that a poi is related in some way to a category. Both pois and
// categories in the links must have been added previously through 'pois'
// and 'categories' field, either on this call or in a previous call to
// 'addData' (see above).
data['links_poi_category'] = [
{'poi' : 'poi1',
'category' : 'cat1'},
{'poi' : 'poi2',
'category' : 'cat2'},
{'poi' : 'poi3',
'category' : 'cat3'},
];
// Add data to the person. 'pois' are pois related to the user, for
// instance, because we know he has liked or visited it. The pois in the
// list must have already been added through the "pois" field, either in
// this call or a previous call to 'addData' (see above), and similar for
// categories.
data['person'] = {
'pois' : ['poi1', 'poi2'],
'categories' : ['cat1', 'cat2'],
};
await Lgcre.addData(data);
// LGCRE: RUNNING A QUERY
// To execute a query, build a map between pois and lists of categories as
// follows
Map<String,dynamic> query = new Map<String,dynamic>();
query['pois'] = [
{ 'poi' : 'poi1',
'categories' : ['cat1, cat2']},
{ 'poi' : 'poi2',
'categories' : ['cat1, cat3']},
{ 'poi' : 'poi3',
'categories' : ['cat2, cat4']},
{ 'poi' : 'poi4',
'categories' : ['cat3, cat4']},
];
// The method run
List<ResultEntry>? result = await Lgcre.run(query);
if(result != null)
{
StringBuffer strbuilder = new StringBuffer();
strbuilder.write('WORKS:\n');
for (ResultEntry entry in result)
{
strbuilder.write(entry.poi+" "+entry.score.toString()+"\n");
}
status = strbuilder.toString();
}
else
{
status = "RUN QUERY RETUNED NULL";
}
// We remove all the data, to test the removeData method
await Lgcre.removeData(data);
// LGCRE: Releasing resources
await Lgcre.release();
} on LgcreException catch (e) {
status = '${e}';
}
catch(e)
{
status = 'Unknown exception thrown';
}
messenger.send(status);
});
}
class _MyAppState extends State<MyApp> {
String _status = 'Unknown';
final isolates = IsolateHandler();
@override
void initState() {
super.initState();
init();
}
Future<void> init() async {
isolates.spawn<String>(useLGCRE,
name: 'useLGCRE',
onReceive: setStatus,
onInitialized: () => isolates.send('Execute', to: 'useLGCRE'));
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, and we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) return;
}
void setStatus(String status)
{
setState(() {
_status = status;
});
isolates.kill('useLGCRE');
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Center(
child: Text(_status)),
),
);
}
}