Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 143 additions & 12 deletions lib/src/core/core.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,27 +22,158 @@ import 'scalar.dart';
import 'termcriteria.dart';
import 'vec.dart';

/// Constants for log levels
const int LOG_LEVEL_SILENT = 0;
const int LOG_LEVEL_FATAL = 1;
const int LOG_LEVEL_ERROR = 2;
const int LOG_LEVEL_WARNING = 3;
const int LOG_LEVEL_INFO = 4;
const int LOG_LEVEL_DEBUG = 5;
const int LOG_LEVEL_VERBOSE = 6;
enum LogLevel {
SILENT(0),
FATAL(1),
ERROR(2),
WARNING(3),
INFO(4),
DEBUG(5),
VERBOSE(6);

final int value;
const LogLevel(this.value);

factory LogLevel.fromValue(int value) {
return switch (value) {
0 => LogLevel.SILENT,
1 => LogLevel.FATAL,
2 => LogLevel.ERROR,
3 => LogLevel.WARNING,
4 => LogLevel.INFO,
5 => LogLevel.DEBUG,
6 => LogLevel.VERBOSE,
_ => throw ArgumentError.value(value, 'value', 'Invalid log level value'),
};
}
}

/// Sets the global logging level.
void setLogLevel(int logLevel) {
cvRun(() => ccore.setLogLevel(logLevel));
void setLogLevel(LogLevel logLevel) {
cvRun(() => ccore.setLogLevel(logLevel.value));
}

/// Gets the global logging level.
int getLogLevel() {
LogLevel getLogLevel() {
final p = calloc<ffi.Int>();
cvRun(() => ccore.getLogLevel(p));
final level = p.value;
calloc.free(p);
return level;
return LogLevel.fromValue(level);
}

void writeLogMessage(LogLevel logLevel, String message) {
final cmsg = message.toNativeUtf8().cast<ffi.Char>();
ccore.writeLogMessage(logLevel.value, cmsg);
calloc.free(cmsg);
}

/// Writes a log message.
///
/// if [tag], [file], [line], [func] are all null, then it will be the same as [writeLogMessage].
void writeLogMessageEx(
LogLevel logLevel,
String message, {
String? tag,
String? file,
int? line,
String? func,
}) {
final cmsg = message.toNativeUtf8().cast<ffi.Char>();

if (tag == null && file == null && line == null && func == null) {
ccore.writeLogMessage(logLevel.value, cmsg);
} else {
final ctag = (tag ?? "").toNativeUtf8().cast<ffi.Char>();
final cfile = (file ?? "").toNativeUtf8().cast<ffi.Char>();
final cfunc = (func ?? "").toNativeUtf8().cast<ffi.Char>();
ccore.writeLogMessageEx(logLevel.value, ctag, cfile, line ?? -1, cfunc, cmsg);
calloc.free(ctag);
calloc.free(cfile);
calloc.free(cfunc);
}

calloc.free(cmsg);
}

void defaultLogCallback(LogLevel logLevel, String message) {
final logMessage = "[dartcv][${logLevel.name}]: $message";
// ignore: avoid_print
print(logMessage);
}

void defaultLogCallbackEx(
LogLevel logLevel,
String tag,
String file,
int line,
String func,
String message,
) {
final logMessage = "[dartcv][${logLevel.name}][$tag]$file:$line:$func: $message";
// ignore: avoid_print
print(logMessage);
}

typedef LogCallbackFunction = void Function(LogLevel logLevel, String message);
typedef LogCallbackExFunction = void Function(
LogLevel logLevel,
String tag,
String file,
int line,
String func,
String message,
);

ffi.NativeCallable<cvg.LogCallbackExFunction>? _logCallbackEx;
ffi.NativeCallable<cvg.LogCallbackFunction>? _logCallback;

void replaceWriteLogMessage({LogCallbackFunction? callback}) {
if (callback == null) {
cvRun(() => ccore.replaceWriteLogMessage(ffi.nullptr));
_logCallback?.close();
_logCallback = null;
} else {
void cCallback(int logLevel, ffi.Pointer<ffi.Char> message, int msgLen) {
final messageStr = message.cast<Utf8>().toDartString(length: msgLen);
callback(LogLevel.fromValue(logLevel), messageStr);
}

final fp = ffi.NativeCallable<cvg.LogCallbackFunction>.listener(cCallback);
cvRun(() => ccore.replaceWriteLogMessage(fp.nativeFunction));
_logCallback = fp;
}
}

void replaceWriteLogMessageEx({LogCallbackExFunction? callback}) {
if (callback == null) {
cvRun(() => ccore.replaceWriteLogMessageEx(ffi.nullptr));
_logCallbackEx?.close();
_logCallbackEx = null;
} else {
void cCallback(
int logLevel,
ffi.Pointer<ffi.Char> tag,
int tagLen,
ffi.Pointer<ffi.Char> file,
int fileLen,
int line,
ffi.Pointer<ffi.Char> func,
int funcLen,
ffi.Pointer<ffi.Char> message,
int msgLen,
) {
final tagStr = tag.cast<Utf8>().toDartString(length: tagLen);
final fileStr = file.cast<Utf8>().toDartString(length: fileLen);
final funcStr = func.cast<Utf8>().toDartString(length: funcLen);
final messageStr = message.cast<Utf8>().toDartString(length: msgLen);
callback(LogLevel.fromValue(logLevel), tagStr, fileStr, line, funcStr, messageStr);
}

final fp = ffi.NativeCallable<cvg.LogCallbackExFunction>.listener(cCallback);
cvRun(() => ccore.replaceWriteLogMessageEx(fp.nativeFunction));
_logCallbackEx = fp;
}
}

/// get version
Expand Down
45 changes: 42 additions & 3 deletions lib/src/g/core.g.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3168,6 +3168,9 @@ external ffi.Pointer<ffi.Char> getCvVersion();
@ffi.Native<LogCallback Function()>()
external LogCallback getLogCallback();

@ffi.Native<LogCallbackEx Function()>()
external LogCallbackEx getLogCallbackEx();

@ffi.Native<ffi.Pointer<CvStatus> Function(ffi.Pointer<ffi.Int>)>()
external ffi.Pointer<CvStatus> getLogLevel(
ffi.Pointer<ffi.Int> logLevel,
Expand All @@ -3176,21 +3179,34 @@ external ffi.Pointer<CvStatus> getLogLevel(
@ffi.Native<LogCallback>()
external LogCallback logCallback;

@ffi.Native<LogCallbackEx>()
external LogCallbackEx logCallbackEx;

@ffi.Native<ffi.Void Function(ErrorCallback)>()
external void registerErrorCallback(
ErrorCallback callback,
);

@ffi.Native<ffi.Pointer<CvStatus> Function(LogCallback)>()
external ffi.Pointer<CvStatus> replaceWriteLogMessageEx(
external ffi.Pointer<CvStatus> replaceWriteLogMessage(
LogCallback callback,
);

@ffi.Native<ffi.Pointer<CvStatus> Function(LogCallbackEx)>()
external ffi.Pointer<CvStatus> replaceWriteLogMessageEx(
LogCallbackEx callback,
);

@ffi.Native<ffi.Void Function(LogCallback)>()
external void setLogCallback(
LogCallback callback,
);

@ffi.Native<ffi.Void Function(LogCallbackEx)>()
external void setLogCallbackEx(
LogCallbackEx callback,
);

@ffi.Native<ffi.Pointer<CvStatus> Function(ffi.Int)>()
external ffi.Pointer<CvStatus> setLogLevel(
int logLevel,
Expand Down Expand Up @@ -6016,6 +6032,24 @@ external void std_VecVecPoint_shrink_to_fit(
ffi.Pointer<VecVecPoint> self,
);

@ffi.Native<ffi.Void Function(ffi.Int, ffi.Pointer<ffi.Char>)>()
external void writeLogMessage(
int logLevel,
ffi.Pointer<ffi.Char> message,
);

@ffi.Native<
ffi.Void Function(ffi.Int, ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>,
ffi.Int, ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>)>()
external void writeLogMessageEx(
int logLevel,
ffi.Pointer<ffi.Char> tag,
ffi.Pointer<ffi.Char> file,
int line,
ffi.Pointer<ffi.Char> func,
ffi.Pointer<ffi.Char> message,
);

const addresses = _SymbolAddresses();

class _SymbolAddresses {
Expand Down Expand Up @@ -6129,7 +6163,8 @@ typedef DartErrorCallbackFunction = void Function(
ffi.Pointer<ffi.Void> userdata);
typedef KeyPoint = imp$1.KeyPoint;
typedef LogCallback = ffi.Pointer<ffi.NativeFunction<LogCallbackFunction>>;
typedef LogCallbackFunction = ffi.Void Function(
typedef LogCallbackEx = ffi.Pointer<ffi.NativeFunction<LogCallbackExFunction>>;
typedef LogCallbackExFunction = ffi.Void Function(
ffi.Int logLevel,
ffi.Pointer<ffi.Char> tag,
ffi.Size tagLen,
Expand All @@ -6140,7 +6175,7 @@ typedef LogCallbackFunction = ffi.Void Function(
ffi.Size funcLen,
ffi.Pointer<ffi.Char> message,
ffi.Size msgLen);
typedef DartLogCallbackFunction = void Function(
typedef DartLogCallbackExFunction = void Function(
int logLevel,
ffi.Pointer<ffi.Char> tag,
int tagLen,
Expand All @@ -6151,6 +6186,10 @@ typedef DartLogCallbackFunction = void Function(
int funcLen,
ffi.Pointer<ffi.Char> message,
int msgLen);
typedef LogCallbackFunction = ffi.Void Function(
ffi.Int logLevel, ffi.Pointer<ffi.Char> message, ffi.Size msgLen);
typedef DartLogCallbackFunction = void Function(
int logLevel, ffi.Pointer<ffi.Char> message, int msgLen);
typedef Mat = imp$1.Mat;
typedef MatStep = imp$1.MatStep;
typedef RNG = imp$1.RNG;
Expand Down
17 changes: 17 additions & 0 deletions lib/src/g/core.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ files:
ErrorCallbackFunction:
name: ErrorCallbackFunction
dart-name: DartErrorCallbackFunction
LogCallbackExFunction:
name: LogCallbackExFunction
dart-name: DartLogCallbackExFunction
LogCallbackFunction:
name: LogCallbackFunction
dart-name: DartLogCallbackFunction
Expand Down Expand Up @@ -752,14 +755,20 @@ files:
name: getCvVersion
c:@F@getLogCallback:
name: getLogCallback
c:@F@getLogCallbackEx:
name: getLogCallbackEx
c:@F@getLogLevel:
name: getLogLevel
c:@F@registerErrorCallback:
name: registerErrorCallback
c:@F@replaceWriteLogMessage:
name: replaceWriteLogMessage
c:@F@replaceWriteLogMessageEx:
name: replaceWriteLogMessageEx
c:@F@setLogCallback:
name: setLogCallback
c:@F@setLogCallbackEx:
name: setLogCallbackEx
c:@F@setLogLevel:
name: setLogLevel
c:@F@std_VecChar_clear:
Expand Down Expand Up @@ -1744,12 +1753,20 @@ files:
name: std_VecVecPoint_set
c:@F@std_VecVecPoint_shrink_to_fit:
name: std_VecVecPoint_shrink_to_fit
c:@F@writeLogMessage:
name: writeLogMessage
c:@F@writeLogMessageEx:
name: writeLogMessageEx
c:@logCallback:
name: logCallback
c:@logCallbackEx:
name: logCallbackEx
c:exception.h@T@ErrorCallback:
name: ErrorCallback
c:logging.h@T@LogCallback:
name: LogCallback
c:logging.h@T@LogCallbackEx:
name: LogCallbackEx
c:math.h@T@double_t:
name: double_t
dart-name: Dartdouble_t
Expand Down
2 changes: 1 addition & 1 deletion src
29 changes: 25 additions & 4 deletions test/core/core_test.dart
Original file line number Diff line number Diff line change
@@ -1,18 +1,39 @@
// ignore_for_file: avoid_print
import 'dart:isolate';

import 'package:dartcv4/dartcv.dart' as cv;
import 'package:test/test.dart';

void main() async {
test('setLogLevel', () {
cv.setLogLevel(cv.LOG_LEVEL_ERROR);
cv.setLogLevel(cv.LogLevel.ERROR);
final level = cv.getLogLevel();
expect(level, equals(cv.LOG_LEVEL_ERROR));
expect(level, equals(cv.LogLevel.ERROR));
});

test('getLogLevel', () {
cv.setLogLevel(cv.LOG_LEVEL_WARNING);
cv.setLogLevel(cv.LogLevel.WARNING);
final level = cv.getLogLevel();
expect(level, equals(cv.LOG_LEVEL_WARNING));
expect(level, equals(cv.LogLevel.WARNING));
});

test('cv.replaceWriteLogMessage', () {
cv.setLogLevel(cv.LogLevel.WARNING);
cv.replaceWriteLogMessage(callback: cv.defaultLogCallback);
Isolate.run(() async {
cv.writeLogMessage(cv.LogLevel.WARNING, 'This is a test log message.');
});
// reset log callback
cv.replaceWriteLogMessage(callback: null);
});

test('cv.replaceWriteLogMessageEx', () {
cv.setLogLevel(cv.LogLevel.WARNING);
cv.replaceWriteLogMessageEx(callback: cv.defaultLogCallbackEx);
Isolate.run(() async {
cv.writeLogMessageEx(cv.LogLevel.WARNING, 'This is a test log message.', file: "core_test.dart");
});
cv.replaceWriteLogMessageEx(callback: null);
});

test('openCvVersion', () async {
Expand Down
Loading