Skip to content

Commit

Permalink
Add context
Browse files Browse the repository at this point in the history
  • Loading branch information
PlugFox committed Oct 16, 2024
1 parent 3611123 commit e3f09d4
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 11 deletions.
7 changes: 3 additions & 4 deletions lib/control.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
library control;
library;

export 'package:control/src/concurrent_controller_handler.dart';
export 'package:control/src/concurrency/concurrency.dart';
export 'package:control/src/controller.dart' hide IController;
export 'package:control/src/controller_scope.dart' hide ControllerScope$Element;
export 'package:control/src/droppable_controller_handler.dart';
export 'package:control/src/sequential_controller_handler.dart';
export 'package:control/src/handler_context.dart' show HandlerContext;
export 'package:control/src/state_consumer.dart';
export 'package:control/src/state_controller.dart' hide IStateController;
3 changes: 3 additions & 0 deletions lib/src/concurrency/concurrency.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export 'package:control/src/concurrency/concurrent_controller_handler.dart';
export 'package:control/src/concurrency/droppable_controller_handler.dart';
export 'package:control/src/concurrency/sequential_controller_handler.dart';
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import 'dart:async';

import 'package:control/src/controller.dart';
import 'package:control/src/handler_context.dart';
import 'package:flutter/foundation.dart' show SynchronousFuture;
import 'package:meta/meta.dart';

/// Sequential controller concurrency
/// Concurrent controller concurrency
base mixin ConcurrentControllerHandler on Controller {
@override
@nonVirtual
Expand All @@ -22,6 +23,8 @@ base mixin ConcurrentControllerHandler on Controller {
Future<void> Function() handler, {
Future<void> Function(Object error, StackTrace stackTrace)? error,
Future<void> Function()? done,
String? name,
Map<String, Object?>? context,
}) {
if (isDisposed) return Future<void>.value(null);
_$processingCalls++;
Expand All @@ -46,6 +49,14 @@ base mixin ConcurrentControllerHandler on Controller {
_done = null;
}

final handlerContext = HandlerContextImpl(
controller: this,
name: name ?? '$runtimeType.handler#${handler.runtimeType}',
context: <String, Object?>{
...?context,
},
);

runZonedGuarded<void>(
() async {
try {
Expand All @@ -63,6 +74,9 @@ base mixin ConcurrentControllerHandler on Controller {
}
},
onError,
zoneValues: <Object?, Object?>{
HandlerContext.key: handlerContext,
},
);

return completer.future;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:async';

import 'package:control/src/controller.dart';
import 'package:control/src/handler_context.dart';
import 'package:flutter/foundation.dart' show SynchronousFuture;
import 'package:meta/meta.dart';

Expand All @@ -22,6 +23,8 @@ base mixin DroppableControllerHandler on Controller {
Future<void> Function() handler, {
Future<void> Function(Object error, StackTrace stackTrace)? error,
Future<void> Function()? done,
String? name,
Map<String, Object?>? context,
}) {
if (isDisposed || isProcessing) return Future<void>.value(null);
_$processingCalls++;
Expand All @@ -46,6 +49,14 @@ base mixin DroppableControllerHandler on Controller {
_done = null;
}

final handlerContext = HandlerContextImpl(
controller: this,
name: name ?? '$runtimeType.handler#${handler.runtimeType}',
context: <String, Object?>{
...?context,
},
);

runZonedGuarded<void>(
() async {
try {
Expand All @@ -63,6 +74,9 @@ base mixin DroppableControllerHandler on Controller {
}
},
onError,
zoneValues: <Object?, Object?>{
HandlerContext.key: handlerContext,
},
);

return completer.future;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'dart:async';
import 'dart:collection';

import 'package:control/src/controller.dart';
import 'package:control/src/handler_context.dart';
import 'package:flutter/foundation.dart' show SynchronousFuture;
import 'package:meta/meta.dart';

Expand All @@ -24,6 +25,8 @@ base mixin SequentialControllerHandler on Controller {
Future<void> Function() handler, {
Future<void> Function(Object error, StackTrace stackTrace)? error,
Future<void> Function()? done,
String? name,
Map<String, Object?>? context,
}) =>
_eventQueue.push<void>(
() {
Expand All @@ -40,6 +43,14 @@ base mixin SequentialControllerHandler on Controller {
}
}

final handlerContext = HandlerContextImpl(
controller: this,
name: name ?? '$runtimeType.handler#${handler.runtimeType}',
context: <String, Object?>{
...?context,
},
);

runZonedGuarded<void>(
() async {
if (isDisposed) return;
Expand All @@ -58,6 +69,9 @@ base mixin SequentialControllerHandler on Controller {
}
},
onError,
zoneValues: <Object?, Object?>{
HandlerContext.key: handlerContext,
},
);

return completer.future;
Expand Down
23 changes: 20 additions & 3 deletions lib/src/controller.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import 'dart:async';

import 'package:control/control.dart';
import 'package:control/src/handler_context.dart';
import 'package:control/src/registry.dart';
import 'package:control/src/state_controller.dart';
import 'package:flutter/foundation.dart'
show ChangeNotifier, Listenable, VoidCallback;
import 'package:meta/meta.dart';
Expand Down Expand Up @@ -37,11 +38,19 @@ abstract interface class IController implements Listenable {
/// Depending on the implementation, the handler may be executed
/// sequentially, concurrently, dropped and etc.
///
/// The [name] parameter is used to identify the handler.
/// The [context] parameter is used to pass additional
/// information to the handler's zone.
///
/// See:
/// - [ConcurrentControllerHandler] - handler that executes concurrently
/// - [SequentialControllerHandler] - handler that executes sequentially
/// - [DroppableControllerHandler] - handler that drops the request when busy
void handle(Future<void> Function() handler);
void handle(
Future<void> Function() handler, {
String? name,
Map<String, Object?>? context,
});
}

/// Controller observer
Expand Down Expand Up @@ -74,6 +83,10 @@ abstract base class Controller with ChangeNotifier implements IController {
);
}

/// Get the handler's context from the current zone.
static HandlerContext? getContext(Controller controller) =>
HandlerContext.zoned();

/// Controller observer
static IControllerObserver? observer;

Expand Down Expand Up @@ -101,7 +114,11 @@ abstract base class Controller with ChangeNotifier implements IController {

@protected
@override
Future<void> handle(Future<void> Function() handler);
Future<void> handle(
Future<void> Function() handler, {
String? name,
Map<String, Object?>? context,
});

@protected
@nonVirtual
Expand Down
43 changes: 43 additions & 0 deletions lib/src/handler_context.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import 'dart:async';

import 'package:control/src/controller.dart';
import 'package:meta/meta.dart';

/// Handler's context.
abstract interface class HandlerContext {
/// Key to access the handler's context.
static const Object key = #handler;

/// Get the handler's context from the current zone.
static HandlerContext? zoned() => switch (Zone.current[HandlerContext.key]) {
HandlerContext context => context,
_ => null,
};

/// Controller that the handler is attached to.
abstract final Controller controller;

/// Name of the handler.
abstract final String name;

/// Extra meta information about the handler.
abstract final Map<String, Object?> context;
}

@internal
final class HandlerContextImpl implements HandlerContext {
HandlerContextImpl({
required this.controller,
required this.name,
required this.context,
});

@override
final Controller controller;

@override
final String name;

@override
final Map<String, Object?> context;
}
5 changes: 5 additions & 0 deletions lib/src/state_controller.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:async';

import 'package:control/src/controller.dart';
import 'package:control/src/handler_context.dart';
import 'package:flutter/foundation.dart';
import 'package:meta/meta.dart';

Expand Down Expand Up @@ -28,6 +29,10 @@ abstract base class StateController<S extends Object> extends Controller
/// State controller
StateController({required S initialState}) : _$state = initialState;

/// Get the handler's context from the current zone.
static HandlerContext? getContext(Controller controller) =>
HandlerContext.zoned();

@override
@nonVirtual
S get state => _$state;
Expand Down
6 changes: 3 additions & 3 deletions pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: control
description: "Simple state management for Flutter with concurrency support."

version: 0.1.0
version: 0.2.0

homepage: https://github.com/PlugFox/control

Expand Down Expand Up @@ -34,7 +34,7 @@ platforms:
# path: example.png

environment:
sdk: '>=3.0.0 <4.0.0'
sdk: '>=3.4.0 <4.0.0'
flutter: ">=3.0.0"

dependencies:
Expand All @@ -45,4 +45,4 @@ dependencies:
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^2.0.0
flutter_lints: ^5.0.0

0 comments on commit e3f09d4

Please sign in to comment.