simplify bundle system

This commit is contained in:
Val Erastov 2022-08-14 20:48:44 -07:00
parent 1363ceb761
commit 02054d62c2
50 changed files with 325 additions and 436 deletions

View file

@ -1,109 +1,95 @@
type BagOfPlugins = Set<Bundle<any, any>>;
export class BundleSystem {
plugins: BagOfPlugins = new Set();
waitingQueue: BagOfPlugins = new Set();
globalContext: any;
activatedBundles = new Set<string>();
waitingQueue = new Set<Bundle<any>>();
perfectLoad = true;
constructor(globalContext: any) {
constructor(globalContext) {
this.globalContext = globalContext;
}
load(plugin: Bundle<any, any>) {
this.waitingQueue.add(plugin);
activate(bundle: Bundle<any>) {
if (!bundle.BundleName) {
console.error("BundleName is not provided for the bundle");
bundle.BundleName = "@Unknown_" + (UNKNOWNS_COUNTER++);
}
if (this.activatedBundles.has(bundle.BundleName)) {
throw `Bundle ${bundle.BundleName} has already activated. Possible name collision`;
}
if (!this.readinessCheck(bundle)) {
this.perfectLoad = false;
this.waitingQueue.add(bundle);
return;
}
this.doActivate(bundle);
this.processWaitingQueue();
}
private doActivate(bundle) {
bundle.activate(this.globalContext);
this.activatedBundles.add(bundle.BundleName);
}
processWaitingQueue() {
let needPass = true;
while (needPass) {
needPass = false;
this.waitingQueue.forEach(plugin => {
const ready = readiness(plugin, this.globalContext);
if (ready) {
try {
plugin.activate(this.globalContext);
checkActivation(plugin, this.globalContext);
needPass = true;
this.plugins.add(plugin);
} catch (error) {
console.error(error);
} finally {
this.waitingQueue.delete(plugin)
for (let bundle of this.waitingQueue) {
if (this.readinessCheck(bundle)) {
this.waitingQueue.delete(bundle);
this.doActivate(bundle);
}
}
})
}
}
unload(plugin: Bundle<any, any>) {
this.waitingQueue.delete(plugin);
this.plugins.delete(plugin);
try {
if (plugin.deactivate) {
plugin.deactivate(this.globalContext);
}
} catch (error) {
console.error(error);
readinessCheck(bundle) {
if (!bundle.activationDependencies) {
return true;
}
let needPass = true;
while (needPass) {
needPass = false;
this.plugins.forEach(plugin => {
if (!plugin.deactivate) {
return;
}
const isReady = readiness(plugin, this.globalContext);
if (!isReady) {
try {
plugin.deactivate(this.globalContext);
this.plugins.delete(plugin);
this.waitingQueue.add(plugin);
needPass = true;
} catch (error) {
console.error(error);
}
}
})
}
}
}
function readiness(plugin: Bundle<any, any>, globalContext: any) {
const specKeys = Object.keys(plugin.inputContextSpec);
for (let key of specKeys) {
if (!globalContext[key] && plugin.inputContextSpec[key] === 'required') {
for (let dep of bundle.activationDependencies) {
if (!this.activatedBundles.has(dep)) {
return false;
}
}
return true;
}
}
function checkActivation(plugin: Bundle<any, any>, globalContext: any) {
const specKeys = Object.keys(plugin.outputContextSpec);
for (let key of specKeys) {
if (!globalContext[key] && plugin.outputContextSpec[key] === 'required') {
console.error("declared service was never activated: " + key);
checkDanglingBundles() {
this.waitingQueue.forEach(dangling => {
const unsatisfied = new Set(dangling.activationDependencies);
this.activatedBundles.forEach(activated => unsatisfied.delete(activated));
console.error('Bundle', dangling.BundleName, 'was never activated because of unsatisfied dependencies: ', Array.from(unsatisfied).join(', '));
})
}
checkPerfectLoad() {
if (!this.perfectLoad) {
console.warn("Bundle activation wasn't perfect. Consider reordering bundles to following:");
console.info(Array.from(this.activatedBundles));
}
}
}
export type Spec = 'required' | 'optional';
export type Spec = 'required';
export type ContextSpec<T> = {
[Property in keyof T]: Spec;
};
export interface Bundle<InputContext, OutputContext, WorkingContext = InputContext&OutputContext> {
export interface Bundle<WorkingContext> {
inputContextSpec: ContextSpec<InputContext>;
activationDependencies?: string[];
outputContextSpec: ContextSpec<OutputContext>;
runtimeDependencies?: string[];
activate(ctx: InputContext&OutputContext);
deactivate?(ctx: InputContext&OutputContext);
activate(ctx: WorkingContext);
BundleName: string,
}
let UNKNOWNS_COUNTER = 0;

View file

@ -0,0 +1,6 @@
export function createBundlerContext() {
}

View file

@ -3,7 +3,7 @@ import {
ALL_EXCLUDING_SOLID_KINDS,
PICK_KIND,
traversePickResults
} from '../../../web/app/cad/scene/controls/pickControlPlugin';
} from 'cad/scene/controls/pickControlBundle';
import {Vector3} from "three";
function waitFor(checkFn) {

View file

@ -4,7 +4,6 @@ import {state, StateStream, Stream} from 'lstream';
import {LOG_FLAGS} from '../logFlags';
import {ApplicationContext} from "cad/context";
import {IconType} from "react-icons";
import {ContextSpec} from "bundler/bundleSystem";
export function activate(context: ApplicationContext) {
@ -160,7 +159,6 @@ export interface ActionSystemBundleContext {
actionService: ActionService;
}
export const outputContextSpec: ContextSpec<ActionSystemBundleContext> = {
actionService: 'required'
}
export const BundleName = "@ActionSystem";

View file

@ -9,7 +9,6 @@ import {AssemblyView} from "./ui/AssemblyView";
import {IoMdConstruct} from "react-icons/io";
import {AssemblyConstraintDefinition} from "./assemblyConstraint";
import {AssemblyConstraintsSchemas} from "./assemblySchemas";
import {ContextSpec} from "bundler/bundleSystem";
export function activate(ctx: ApplicationContext) {
@ -105,6 +104,4 @@ export interface AssemblyBundleContext {
assemblyService: AssemblyService;
}
export const outputContextSpec: ContextSpec<AssemblyBundleContext> = {
assemblyService: 'required'
}
export const BundleName = "@Assembly";

View file

@ -2,31 +2,22 @@ import {Bundle} from "bundler/bundleSystem";
import {AttributesService} from "cad/attributes/attributesService";
import {contributeComponent} from "cad/dom/components/ContributedComponents";
import {DisplayOptionsDialogManager} from "cad/attributes/ui/DisplayOptionsDialog";
import {ActionSystemBundleContext} from "cad/actions/actionSystemBundle";
import {RequiresAnyModelSelection} from "cad/actions/actionHelpers";
import {IoColorPalette} from "react-icons/io5";
import {FaTable} from "react-icons/fa";
import {ApplicationContext} from "cad/context";
type AttributesPluginInputContext = ActionSystemBundleContext;
export interface AttributesPluginContext {
export interface AttributesBundleContext {
attributesService: AttributesService;
}
type AttributesPluginWorkingContext = AttributesPluginInputContext&AttributesPluginContext;
export const AttributesBundle: Bundle<ApplicationContext> = {
export const AttributesBundle: Bundle<AttributesPluginInputContext, AttributesPluginContext, AttributesPluginWorkingContext> = {
activationDependencies: [
'@ActionSystem'
],
inputContextSpec: {
actionService: 'required',
},
outputContextSpec: {
attributesService: 'required',
},
activate(ctx: AttributesPluginWorkingContext) {
activate(ctx: ApplicationContext) {
ctx.attributesService = new AttributesService();
contributeComponent(DisplayOptionsDialogManager);
@ -55,6 +46,7 @@ export const AttributesBundle: Bundle<AttributesPluginInputContext, AttributesPl
])
},
BundleName: "@Attributes",
}

View file

@ -0,0 +1,22 @@
import {Bundle} from "bundler/bundleSystem";
import {ApplicationContext} from "cad/context";
export interface LegacyStructureBundleContext {
services: any,
streams: any
}
export const LegacyStructureBundle: Bundle<ApplicationContext> = {
activate(ctx: ApplicationContext) {
ctx.services = {};
ctx.streams = {};
},
BundleName: "@Legacy",
}

View file

@ -1,52 +1,48 @@
import {ProjectBundleContext} from "cad/projectBundle";
import {ActionSystemBundleContext} from "cad/actions/actionSystemBundle";
import {AssemblyBundleContext} from "cad/assembly/assemblyBundle";
import {AttributesPluginContext} from "cad/attributes/attributesBundle";
import {AttributesBundleContext} from "cad/attributes/attributesBundle";
import {CadRegistryBundleContext} from "cad/craft/cadRegistryBundle";
import {CraftBundleContext} from "cad/craft/craftBundle";
import {OperationBundleContext} from "cad/craft/operationBundle";
import {OCCBundleContext} from "cad/craft/e0/occtBundle";
import {WizardPluginContext} from "cad/craft/wizard/wizardBundle";
import {WizardBundleContext} from "cad/craft/wizard/wizardBundle";
import {AppTabsBundleContext} from "cad/dom/appTabsBundle";
import {DomPluginContext} from "cad/dom/domBundle";
import {DomBundleContext} from "cad/dom/domBundle";
import {UIBundleContext} from "cad/dom/uiBundle";
import {ExpressionBundleContext} from "cad/expressions/expressionsBundle";
import {LocationBundleContext} from "cad/location/LocationBundle";
import {RemotePartsBundleContext} from "cad/partImport/remotePartsBundle";
import {ProjectManagerBundleContext} from "cad/projectManager/projectManagerBundle";
import {EntityContextBundleContext} from "cad/scene/entityContextBundle";
import {HighlightPluginContext} from "cad/scene/highlightBundle";
import {HighlightBundleContext} from "cad/scene/highlightBundle";
import {SceneBundleContext} from "cad/scene/sceneBundle";
import {SketcherBundleContext} from "cad/sketch/sketcherBundle";
import {SketchStorageBundleContext} from "cad/sketch/sketchStorageBundle";
import {StorageBundleContext} from "cad/storage/storageBundle";
import {WorkbenchBundleContext} from "cad/workbench/workbenchBundle";
export interface LegacyContext {
services: any,
streams: any,
}
import {LegacyStructureBundleContext} from "cad/context/LegacyStructureBundle";
export interface ApplicationContext extends
LegacyContext,
LegacyStructureBundleContext,
ProjectBundleContext,
ActionSystemBundleContext,
AssemblyBundleContext,
AttributesPluginContext,
AttributesBundleContext,
CadRegistryBundleContext,
CraftBundleContext,
OperationBundleContext,
OCCBundleContext,
WizardPluginContext,
WizardBundleContext,
AppTabsBundleContext,
DomPluginContext,
DomBundleContext,
UIBundleContext,
ExpressionBundleContext,
LocationBundleContext,
RemotePartsBundleContext,
ProjectManagerBundleContext,
EntityContextBundleContext,
HighlightPluginContext,
HighlightBundleContext,
SceneBundleContext,
SketcherBundleContext,
SketchStorageBundleContext,
@ -56,10 +52,5 @@ export interface ApplicationContext extends
export type CoreContext = ApplicationContext;
export default {
services: {},
streams: {}
} as ApplicationContext;
export default {} as ApplicationContext;

View file

@ -114,6 +114,4 @@ export interface CadRegistryBundleContext {
cadRegistry: CadRegistry;
}
export const outputContextSpec: ContextSpec<CadRegistryBundleContext> = {
cadRegistry: 'required'
}
export const BundleName = "@CadRegistry";

View file

@ -297,6 +297,4 @@ export interface CraftBundleContext {
craftService: CraftService;
}
export const outputContextSpec: ContextSpec<CraftBundleContext> = {
craftService: 'required'
}
export const BundleName = "@Craft";

View file

@ -1,6 +0,0 @@
import defaultCraftEngine from './defaultCraftEngine';
export function activate(ctx) {
ctx.services.craftEngine = defaultCraftEngine
}

View file

@ -1,6 +1,8 @@
import {state} from 'lstream';
import {EMPTY_OBJECT} from 'gems/objects';
export const BundleName = "@CraftUI";
export function activate({streams}) {
streams.ui.craft = {
modificationSelection: state(EMPTY_OBJECT)

View file

@ -1,7 +1,6 @@
import {GenericWASMEngine_V1} from "engine/impl/wasm/GenericWASMEngine_V1";
import {CraftEngine} from "./craftEngine";
import {createOCCService, OCCService} from "cad/craft/e0/occService";
import {ContextSpec} from "bundler/bundleSystem";
export interface OCCBundleContext {
@ -55,10 +54,7 @@ function loadWasm(ctx) {
document.head.appendChild(mainScript);
}
export const outputContextSpec: ContextSpec<OCCBundleContext> = {
craftEngine: 'required',
occService: 'required'
}
export const BundleName = "@OCCT";

View file

@ -1,5 +1,7 @@
import {STORAGE_GLOBAL_PREFIX} from '../projectBundle';
export const BundleName = "@Extensions";
const EXTENSIONS_STORAGE_PREFIX = `${STORAGE_GLOBAL_PREFIX}.Extensions`;
let extensions = [];

View file

@ -10,11 +10,9 @@ import {Types} from "cad/craft/schema/types";
import {EntityTypeSchema} from "cad/craft/schema/types/entityType";
import {FlattenPath, ParamsPath} from "cad/craft/wizard/wizardTypes";
import {IconDeclaration} from "cad/icons/IconDeclaration";
import {resolveIcon} from "cad/craft/ui/iconResolver";
import {loadDeclarativeForm} from "cad/mdf/declarativeFormLoader";
import {operationIconToActionIcon} from "cad/craft/operationHelper";
import {GenerateWorkbenchOperationDocumentationLink} from "doc/documentationHelper";
import {ContextSpec} from "bundler/bundleSystem";
export function activate(ctx: ApplicationContext) {
@ -239,8 +237,6 @@ export interface OperationBundleContext {
operationService: OperationService;
}
export const outputContextSpec: ContextSpec<OperationBundleContext> = {
operationService: 'required'
}
export const BundleName = "@Operation";

View file

@ -183,15 +183,12 @@ export function activate(ctx: ApplicationContext) {
ctx.wizardService = services.wizard = wizardService;
}
export interface WizardPluginContext {
export interface WizardBundleContext {
wizardService: WizardService
}
export const outputContextSpec: ContextSpec<WizardPluginContext> = {
wizardService: 'required'
}
function applyOverrides(params, initialOverrides) {
Object.assign(params, initialOverrides);
}
export const BundleName = "@Wizard";

View file

@ -1,34 +1,29 @@
import {FACE, SHELL} from 'cad/model/entities';
import {FACE} from 'cad/model/entities';
import {OperationRequest} from "cad/craft/craftBundle";
import {ParamsPath, WizardService} from "cad/craft/wizard/wizardTypes";
import {OperationParamPrimitive} from "cad/craft/schema/schema";
import {EntityReference} from "cad/craft/operationBundle";
import {Bundle} from "bundler/bundleSystem";
import {MarkerPluginContext} from "cad/scene/selectionMarker/markerPlugin";
import {WizardPluginContext} from "cad/craft/wizard/wizardBundle";
import {PickControlPluginContext} from "cad/scene/controls/pickControlPlugin";
import {MarkerBundleContext} from "cad/scene/selectionMarker/markerBundle";
import {WizardBundleContext} from "cad/craft/wizard/wizardBundle";
import {PickControlBundleContext} from "cad/scene/controls/pickControlBundle";
import _ from "lodash";
import {MObject} from "cad/model/mobject";
export type WizardSelectionPluginInputContext = MarkerPluginContext & WizardPluginContext & PickControlPluginContext;
type WizardSelectionBundleActivationContext = MarkerBundleContext & WizardBundleContext & PickControlBundleContext;
export interface WizardSelectionPluginContext {
export interface WizardSelectionBundleContext {
}
export type WizardSelectionWorkingContext = WizardSelectionPluginInputContext & WizardSelectionPluginContext;
export type WizardSelectionBundleWorkingContext = WizardSelectionBundleActivationContext & WizardSelectionBundleContext;
export const WizardSelectionPlugin: Bundle<WizardSelectionPluginInputContext, WizardSelectionPluginContext, WizardSelectionWorkingContext> = {
export const WizardSelectionBundle: Bundle<WizardSelectionBundleWorkingContext> = {
inputContextSpec: {
markerService: 'required',
pickControlService: 'required',
wizardService: 'required'
},
activationDependencies: [
'@Marker', '@Wizard', '@PickControl'
],
outputContextSpec: {
},
activate(ctx: WizardSelectionWorkingContext) {
activate(ctx: WizardSelectionBundleWorkingContext) {
const wizardService = ctx.wizardService;
let wizardPickHandler = null;
@ -70,6 +65,8 @@ export const WizardSelectionPlugin: Bundle<WizardSelectionPluginInputContext, Wi
});
},
BundleName: "@WizardSelection",
}
function createPickHandlerFromSchema(wizardService: WizardService) {

View file

@ -10,6 +10,8 @@ import curveTess from 'geom/impl/curve/curve-tess';
import {LOG_FLAGS} from './logFlags';
import {state} from "lstream";
export const BundleName = "@Debug";
const BREP_DEBUG_WINDOW_VISIBLE$ = state(false);
export function activate(ctx) {

View file

@ -1,4 +0,0 @@
export function activate() {
}

View file

@ -1,6 +1,5 @@
import {state, StateStream} from "lstream";
import {ApplicationContext} from "cad/context";
import {ContextSpec} from "bundler/bundleSystem";
export function activate(ctx: ApplicationContext) {
@ -83,6 +82,4 @@ export interface AppTabsBundleContext {
appTabsService: AppTabsService;
}
export const outputContextSpec: ContextSpec<AppTabsBundleContext> = {
appTabsService: 'required'
}
export const BundleName = "@AppTabs";

View file

@ -3,7 +3,7 @@ import ControlBar, {ControlBarButton} from './ControlBar';
import connect from 'ui/connect';
import Fa from 'ui/components/Fa';
import {toIdAndOverrides} from '../../actions/actionRef';
import {isMenuAction} from '../menu/menuPlugin';
import {isMenuAction} from '../menu/menuBundle';
import {menuAboveElementHint} from '../menu/menuUtils';
import {useStream} from "ui/effects";
import {ActionButtonBehavior} from "../../actions/ActionButtonBehavior";

View file

@ -1,6 +1,7 @@
import {contributeComponent} from './components/ContributedComponents';
import {Bundle} from "bundler/bundleSystem";
import {AppTabsService} from "cad/dom/appTabsBundle";
import {LegacyStructureBundle, LegacyStructureBundleContext} from "cad/context/LegacyStructureBundle";
export interface DomService {
@ -12,29 +13,25 @@ export interface DomService {
}
interface DomPluginInputContext {
interface DomBundleActivationContext extends LegacyStructureBundleContext {
appTabsService: AppTabsService;
services: any;
}
export interface DomPluginContext {
export interface DomBundleContext {
domService: DomService;
}
type DomPluginWorkingContext = DomPluginInputContext&DomPluginContext;
type DomBundleWorkingContext = DomBundleActivationContext&DomBundleContext;
export const DomBundle: Bundle<DomPluginInputContext, DomPluginContext, DomPluginWorkingContext> = {
inputContextSpec: {
appTabsService: 'required',
services: 'required',
},
export const DomBundle: Bundle<DomBundleWorkingContext> = {
outputContextSpec: {
domService: 'required',
},
activationDependencies: [
'@AppTabs',
LegacyStructureBundle.BundleName
],
activate(ctx: DomPluginInputContext&DomPluginContext) {
activate(ctx: DomBundleWorkingContext) {
ctx.domService = {
viewerContainer: document.getElementById('viewer-container'),
contributeComponent,
@ -56,6 +53,8 @@ export const DomBundle: Bundle<DomPluginInputContext, DomPluginContext, DomPlugi
});
},
BundleName: "@Dom",
}

View file

@ -1,5 +1,7 @@
import {state} from 'lstream';
export const BundleName = "@Menu";
export function activate(ctx) {
const {services, streams} = ctx;

View file

@ -76,7 +76,4 @@ export interface UIBundleContext {
};
}
export const outputContextSpec: ContextSpec<UIBundleContext> = {
uiService: undefined
}
export const BundleName = "@UI";

View file

@ -1,6 +1,8 @@
import {STLExporter} from './stl/stlExporter';
import exportTextData from 'gems/exportTextData';
export const BundleName = "@Export";
export function activate(ctx) {
function toStlAsciiString() {

View file

@ -1,6 +1,8 @@
import exposure from './exposure';
import {MBrepShell} from '../model/mshell';
export const BundleName = "@Exposure";
/*
* exposure stands for the Test Program Interface
*/

View file

@ -1,8 +1,8 @@
import {merge, state, StateStream, Stream} from 'lstream';
import {indexArray} from 'gems/iterables';
import {CoreContext} from "cad/context";
import {ContextSpec} from "bundler/bundleSystem";
export const BundleName = "@Expressions";
export function activate(ctx: CoreContext) {
let _evaluateExpression: (string) => any = () => {};
@ -120,9 +120,3 @@ export interface ExpressionBundleContext {
expressionService: ExpressionService;
}
export const outputContextSpec: ContextSpec<ExpressionBundleContext> = {
expressionService: 'required'
}

View file

@ -37,3 +37,5 @@ export function activate(ctx) {
}
}
}
export const BundleName = "@Lifecycle";

View file

@ -1,141 +1,117 @@
import * as LifecyclePlugin from './lifecyclePlugin';
import * as AppTabsPlugin from '../dom/appTabsBundle';
import * as LifecycleBundle from './lifecycleBundle';
import * as AppTabsBundle from '../dom/appTabsBundle';
import {DomBundle} from '../dom/domBundle';
import * as PickControlPlugin from '../scene/controls/pickControlPlugin';
import * as MouseEventSystemPlugin from '../scene/controls/mouseEventSystemPlugin';
import * as ScenePlugin from '../scene/sceneBundle';
import * as MarkerPlugin from '../scene/selectionMarker/markerPlugin';
import * as ActionSystemPlugin from '../actions/actionSystemBundle';
import * as UiPlugin from '../dom/uiBundle';
import * as MenuPlugin from '../dom/menu/menuPlugin';
import * as KeyboardPlugin from '../keyboard/keyboardPlugin';
import * as WizardPlugin from '../craft/wizard/wizardBundle';
import {WizardSelectionPlugin} from '../craft/wizard/wizardSelectionPlugin';
import * as PreviewPlugin from '../preview/previewPlugin';
import * as OperationPlugin from '../craft/operationBundle';
import * as ExtensionsPlugin from '../craft/extensionsPlugin';
import * as CadRegistryPlugin from '../craft/cadRegistryBundle';
import * as CraftPlugin from '../craft/craftBundle';
import * as RemotePartsPlugin from '../partImport/remotePartsBundle';
import * as CraftUiPlugin from '../craft/craftUiPlugin';
import * as StoragePlugin from '../storage/storageBundle';
import * as ProjectPlugin from '../projectBundle';
import * as ProjectManagerPlugin from '../projectManager/projectManagerBundle';
import * as SketcherPlugin from '../sketch/sketcherBundle';
import * as SketcherStoragePlugin from '../sketch/sketchStorageBundle';
import * as ExportPlugin from '../exportPlugin';
import * as ExposurePlugin from '../exposure/exposurePlugin';
import {ViewSyncPlugin} from '../scene/viewSyncPlugin';
import * as PickControlBundle from '../scene/controls/pickControlBundle';
import * as MouseEventSystemBundle from '../scene/controls/mouseEventSystemBundle';
import * as SceneBundle from '../scene/sceneBundle';
import * as MarkerBundle from '../scene/selectionMarker/markerBundle';
import * as ActionSystemBundle from '../actions/actionSystemBundle';
import * as UIBundle from '../dom/uiBundle';
import * as MenuBundle from '../dom/menu/menuBundle';
import * as KeyboardBundle from '../keyboard/keyboardBundle';
import * as WizardBundle from '../craft/wizard/wizardBundle';
import {WizardSelectionBundle} from '../craft/wizard/wizardSelectionBundle';
import * as PreviewBundle from '../preview/previewBundle';
import * as OperationBundle from '../craft/operationBundle';
import * as ExtensionsBundle from '../craft/extensionsBundle';
import * as CadRegistryBundle from '../craft/cadRegistryBundle';
import * as CraftBundle from '../craft/craftBundle';
import * as RemotePartsBundle from '../partImport/remotePartsBundle';
import * as CraftUIBundle from '../craft/craftUIBundle';
import * as StorageBundle from '../storage/storageBundle';
import * as ProjectBundle from '../projectBundle';
import * as ProjectManagerBundle from '../projectManager/projectManagerBundle';
import * as SketcherBundle from '../sketch/sketcherBundle';
import * as SketcherStorageBundle from '../sketch/sketchStorageBundle';
import * as ExportBundle from '../exportBundle';
import * as ExposureBundle from '../exposure/exposureBundle';
import {ViewSyncBundle} from '../scene/viewSyncBundle';
import * as EntityContextPlugin from '../scene/entityContextBundle';
import * as OCCTPlugin from '../craft/e0/occtBundle';
import context from 'cad/context';
import * as OCCTBundle from '../craft/e0/occtBundle';
import startReact from "../dom/startReact";
import * as UIConfigPlugin from "../workbench/uiConfigPlugin";
import * as DebugPlugin from "../debugPlugin";
import * as ExpressionsPlugin from "../expressions/expressionsBundle";
import * as UIConfigBundle from "../workbench/uiConfigBundle";
import * as DebugBundle from "../debugBundle";
import * as ExpressionsBundle from "../expressions/expressionsBundle";
import {WorkbenchBundle} from "../workbench/workbenchBundle";
import * as LocationPlugin from "../location/LocationBundle";
import * as AssemblyPlugin from "../assembly/assemblyBundle";
import {WorkbenchesLoaderPlugin} from "cad/workbench/workbenchesLoaderPlugin";
import {BundleSystem} from "bundler/bundleSystem";
import * as LocationBundle from "../location/LocationBundle";
import * as AssemblyBundle from "../assembly/assemblyBundle";
import {WorkbenchesLoaderBundle} from "cad/workbench/workbenchesLoaderBundle";
import {AttributesBundle} from "cad/attributes/attributesBundle";
import {HighlightBundle} from "cad/scene/highlightBundle";
import {LegacyStructureBundle} from "cad/context/LegacyStructureBundle";
import context from "cad/context";
import {BundleSystem} from "bundler/bundleSystem";
export default function startApplication(callback) {
let preUIPlugins = [
LifecyclePlugin,
ProjectPlugin,
StoragePlugin,
AppTabsPlugin,
ActionSystemPlugin,
UiPlugin,
MenuPlugin,
KeyboardPlugin,
ExpressionsPlugin,
OperationPlugin,
CraftPlugin,
ExtensionsPlugin,
SketcherStoragePlugin,
WizardPlugin,
PreviewPlugin,
CraftUiPlugin,
CadRegistryPlugin,
ExportPlugin,
ExposurePlugin,
OCCTPlugin,
ProjectManagerPlugin
let preUIBundles = [
LifecycleBundle,
ProjectBundle,
StorageBundle,
AppTabsBundle,
ActionSystemBundle,
UIBundle,
MenuBundle,
KeyboardBundle,
ExpressionsBundle,
OperationBundle,
CraftBundle,
ExtensionsBundle,
SketcherStorageBundle,
WizardBundle,
PreviewBundle,
CraftUIBundle,
CadRegistryBundle,
ExportBundle,
ExposureBundle,
OCCTBundle,
ProjectManagerBundle
];
let plugins = [
let bundles = [
DomBundle,
ScenePlugin,
MouseEventSystemPlugin,
MarkerPlugin,
PickControlPlugin,
SceneBundle,
MouseEventSystemBundle,
MarkerBundle,
PickControlBundle,
EntityContextPlugin,
WorkbenchesLoaderPlugin,
WorkbenchesLoaderBundle,
WorkbenchBundle,
SketcherPlugin,
UIConfigPlugin,
DebugPlugin,
LocationPlugin,
AssemblyPlugin,
RemotePartsPlugin,
ViewSyncPlugin,
WizardSelectionPlugin,
SketcherBundle,
UIConfigBundle,
DebugBundle,
LocationBundle,
AssemblyBundle,
RemotePartsBundle,
ViewSyncBundle,
WizardSelectionBundle,
AttributesBundle,
HighlightBundle
];
let allPlugins = [...preUIPlugins, ...plugins];
const pluginSystem = new BundleSystem(context);
context.pluginSystem = pluginSystem;
const allBundle = [...preUIBundles, ...bundles];
const bundleSystem = new BundleSystem(context);
defineStreams(allPlugins, context);
bundleSystem.activate(LegacyStructureBundle);
allBundle.forEach(bundle => {
if (bundle.defineStreams) {
bundle.defineStreams(context);
}
});
activatePlugins(preUIPlugins, pluginSystem);
preUIBundles.forEach(bundle => {
bundleSystem.activate(bundle);
});
startReact(context, () => {
activatePlugins(plugins, pluginSystem);
bundles.forEach(bundle => {
bundleSystem.activate(bundle);
});
context.services.lifecycle.declareAppReady();
context.services.viewer.render();
context.viewer.render();
callback(context);
});
}
export function defineStreams(plugins, context) {
for (let plugin of plugins) {
if (plugin.defineStreams) {
plugin.defineStreams(context);
}
}
}
function adapter(oldStylePlugin) {
if (oldStylePlugin.inputContextSpec) {
return oldStylePlugin;
}
return {
inputContextSpec: {},
outputContextSpec: {},
activate: oldStylePlugin.activate,
deactivate: ctx => {}
}
}
export function activatePlugins(plugins, pluginSystem) {
for (let plugin of plugins) {
pluginSystem.load(adapter(plugin));
}
bundleSystem.checkDanglingBundles();
bundleSystem.checkPerfectLoad();
}

View file

@ -1,8 +1,10 @@
import Mousetrap from 'mousetrap';
import DefaultKeymap from './keymaps/default';
import {isMenuAction} from '../dom/menu/menuPlugin';
import {isMenuAction} from '../dom/menu/menuBundle';
import {state} from 'lstream';
export const BundleName = "@Keyboard";
export function activate(ctx) {
const {services, streams} = ctx;

View file

@ -2,7 +2,6 @@ import {state, StateStream} from "lstream";
import {ApplicationContext} from "cad/context";
import {MShell} from "../model/mshell";
import {LocationDialog} from "./LocationDialog";
import {ContextSpec} from "bundler/bundleSystem";
export function activate(ctx: ApplicationContext) {
@ -41,7 +40,4 @@ export interface LocationBundleContext {
locationService: LocationService;
}
export const outputContextSpec: ContextSpec<LocationBundleContext> = {
locationService: 'required'
}
export const BundleName = "@Location";

View file

@ -1,22 +1,18 @@
import {ApplicationContext, CoreContext} from "cad/context";
import {ApplicationContext} from "cad/context";
import {Repository} from "../repository/repository";
import {IconType} from "react-icons";
import {Emitter, stream} from "lstream";
import {ShowDialogRequest} from "ui/showDialogRequest";
import {CatalogPartChooser} from "./ui/CatalogPartChooser";
import {ImportPartOperation} from "./importPartOperation/importPartOperation";
import {MObject, MObjectIdGenerator} from "../model/mobject";
import {WEB_CAD_ORG_PARTS_REPO, WEB_CAD_ORG_COMMONS_CATALOG} from "./remotePartsConfig";
import {indexById} from "gems/iterables";
import {ModelBundle} from "../projectManager/projectManagerBundle";
import {PartRepository} from "./partRepository";
import {initProjectService} from "../projectBundle";
import {activate as activateCraftPlugin} from '../craft/craftBundle';
import {activate as activateExpressionsPlugin} from '../expressions/expressionsBundle';
import {activate as activateCadRegistryPlugin} from '../craft/cadRegistryBundle';
import {activate as activateStoragePlugin} from '../storage/storageBundle';
import {activate as activateSketchStoragePlugin} from '../sketch/sketchStorageBundle';
import {ContextSpec} from "bundler/bundleSystem";
import {activate as activateCraftBundle} from '../craft/craftBundle';
import {activate as activateExpressionsBundle} from '../expressions/expressionsBundle';
import {activate as activateCadRegistryBundle} from '../craft/cadRegistryBundle';
import {activate as activateStorageBundle} from '../storage/storageBundle';
import {activate as activateSketchStorageBundle} from '../sketch/sketchStorageBundle';
export function activate(ctx: ApplicationContext) {
@ -75,12 +71,12 @@ export function activate(ctx: ApplicationContext) {
};
initProjectService(evalContext, partRef, {});
activateStoragePlugin(evalContext);
activateSketchStoragePlugin(evalContext);
activateExpressionsPlugin(evalContext);
activateCraftPlugin(evalContext);
activateStorageBundle(evalContext);
activateSketchStorageBundle(evalContext);
activateExpressionsBundle(evalContext);
activateCraftBundle(evalContext);
// @ts-ignore
activateCadRegistryPlugin(evalContext);
activateCadRegistryBundle(evalContext);
// initProject(evalContext, partRef, {});
evalContext.expressionService.load(projectModel.expressions);
@ -185,7 +181,5 @@ export interface RemotePartsBundleContext {
remotePartsService: RemotePartsService;
}
export const outputContextSpec: ContextSpec<RemotePartsBundleContext> = {
remotePartsService: 'required'
}
export const BundleName = "@RemoteParts";

View file

@ -1,11 +0,0 @@
import * as DomPlugin from './dom/domBundle';
import * as PickControlPlugin from './scene/controls/pickControlPlugin';
import * as ScenePlugin from './scene/sceneBundle';
import * as SelectionMarkerPlugin from './scene/selectionMarker/markerPlugin';
export default [
DomPlugin,
ScenePlugin,
PickControlPlugin,
SelectionMarkerPlugin
]

View file

@ -1,6 +1,8 @@
import {createPreviewer} from './scenePreviewer';
import {ApplicationContext} from "cad/context";
export const BundleName = "@Preview";
export function activate(ctx: ApplicationContext) {
let previewer = null;
ctx.wizardService.materializedWorkingRequest$.attach(materializedWorkingRequest => {

View file

@ -5,7 +5,6 @@ import {ApplicationContext} from "cad/context";
import {ProjectModel} from "./projectManager/projectManagerBundle";
import {DebugMode$} from "debugger/Debugger";
import {fillUpMissingFields} from "cad/craft/schema/initializeBySchema";
import {ContextSpec} from "bundler/bundleSystem";
export const STORAGE_GLOBAL_PREFIX = 'TCAD';
export const PROJECTS_PREFIX = `${STORAGE_GLOBAL_PREFIX}.projects.`;
@ -192,8 +191,5 @@ export interface ProjectBundleContext {
}
export const outputContextSpec: ContextSpec<ProjectBundleContext> = {
projectService: 'required'
}
export const BundleName = "@Project";

View file

@ -5,7 +5,6 @@ import {SketchFormat_V3} from "sketcher/io";
import {ApplicationContext} from "cad/context";
import {OperationRequest} from "../craft/craftBundle";
import {AssemblyConstraintDefinition} from "cad/assembly/assemblyConstraint";
import {ContextSpec} from "bundler/bundleSystem";
export function activate(ctx: ApplicationContext) {
@ -253,6 +252,4 @@ export interface ProjectManagerBundleContext {
projectManager: IProjectManager;
}
export const outputContextSpec: ContextSpec<ProjectManagerBundleContext> = {
projectManager: 'required'
}
export const BundleName = "@ProjectManager";

View file

@ -1,3 +0,0 @@
import {GitHubRepoRepository} from "./GitHubRepoRepository";
new GitHubRepoRepository('xibyte/jsketcher', 'master');

View file

@ -2,6 +2,8 @@ import {printRaycastDebugInfo, RayCastDebugInfo} from "./rayCastDebug";
import {LOG_FLAGS} from "cad/logFlags";
import {stream} from "lstream";
export const BundleName = "@MouseEventSystem";
const MouseStates = {
IDLE: 'IDLE',
DOWN: 'DOWN'

View file

@ -29,7 +29,7 @@ export interface PickControlService {
simulatePickFromRay()
}
export interface PickControlPluginContext {
export interface PickControlBundleContext {
pickControlService: PickControlService;
}
@ -340,3 +340,5 @@ function printPickInfo(model, rayCastData?) {
printRaycastDebugInfo('selection', rayCastData);
}
}
export const BundleName = "@PickControl";

View file

@ -1,9 +1,8 @@
import {combine, state, StateStream, Stream} from 'lstream';
import {combine, state, StateStream} from 'lstream';
import {addToListInMap, EMPTY_ARRAY} from 'gems/iterables';
import {DATUM, EDGE, FACE, LOOP, SHELL, SKETCH_OBJECT} from '../model/entities';
import {MObject} from "cad/model/mobject";
import {ContextSpec} from "bundler/bundleSystem";
export const SELECTABLE_ENTITIES = [FACE, EDGE, SKETCH_OBJECT, DATUM, SHELL];
@ -72,6 +71,4 @@ export interface EntityContextBundleContext {
};
}
export const outputContextSpec: ContextSpec<EntityContextBundleContext> = {
entityContextService: 'required'
}
export const BundleName = "@EntityContext";

View file

@ -1,7 +1,6 @@
import {Bundle} from "bundler/bundleSystem";
import {combine, merge, Stream, stream} from "lstream";
import Viewer from "cad/scene/viewer";
import {ScanStream} from "lstream/scan";
export class HighlightService {
@ -43,30 +42,23 @@ export class HighlightService {
}
interface HighlightPluginInputContext {
interface HighlightBundleInputContext {
viewer: Viewer;
}
export interface HighlightPluginContext {
export interface HighlightBundleContext {
highlightService: HighlightService;
}
type HighlightPluginWorkingContext = HighlightPluginInputContext&HighlightPluginContext;
type HighlightBundleWorkingContext = HighlightBundleInputContext&HighlightBundleContext;
export const HighlightBundle: Bundle<HighlightPluginInputContext, HighlightPluginContext, HighlightPluginWorkingContext> = {
export const HighlightBundle: Bundle<HighlightBundleWorkingContext> = {
inputContextSpec: {
viewer: 'required',
},
outputContextSpec: {
highlightService: 'required',
},
activate(ctx: HighlightPluginWorkingContext) {
activate(ctx: HighlightBundleWorkingContext) {
ctx.highlightService = new HighlightService(ctx.viewer);
},
BundleName: "@Highlight",
}

View file

@ -1,8 +1,6 @@
import Viewer from './viewer';
import CadScene from './cadScene';
import {externalState, stream} from 'lstream';
import {ApplicationContext} from "cad/context";
import {ContextSpec} from "bundler/bundleSystem";
export function activate(ctx: ApplicationContext) {
const {services} = ctx;
@ -58,7 +56,4 @@ export interface SceneBundleContext {
viewer: Viewer;
}
export const outputContextSpec: ContextSpec<SceneBundleContext> = {
cadScene: 'required',
viewer: 'required'
}
export const BundleName = "@Scene";

View file

@ -2,6 +2,8 @@ import {OrderedMap} from 'gems/linkedMap';
import {eventStream, Stream} from 'lstream';
import {MObject} from "cad/model/mobject";
export const BundleName = "@Marker";
export interface MarkerService {
clear();
@ -24,7 +26,7 @@ export interface MarkerService {
$markedEntities: Stream<MObject>
}
export interface MarkerPluginContext {
export interface MarkerBundleContext {
markerService: MarkerService;
}

View file

@ -7,16 +7,17 @@ import {MShell} from '../model/mshell';
import {MDatum} from '../model/mdatum';
import DatumView from './views/datumView';
import {View} from './views/view';
import {HighlightBundle} from "cad/scene/highlightBundle";
import {AttributesBundle} from "cad/attributes/attributesBundle";
export const ViewSyncPlugin = {
export const ViewSyncBundle = {
inputContextSpec: {
highlightService: 'required',
attributesService: 'required',
},
BundleName: "@ViewSync",
outputContextSpec: {
},
activationDependencies: [
HighlightBundle.BundleName,
AttributesBundle.BundleName
],
activate(ctx) {
let {streams} = ctx;

View file

@ -74,8 +74,5 @@ export interface SketchStorageBundleContext {
sketchStorageService: SketchStorageService;
}
export const outputContextSpec: ContextSpec<SketchStorageBundleContext> = {
sketchStorageService: 'required'
}
export const BundleName = "@SketchStorage";

View file

@ -206,6 +206,4 @@ export interface SketcherBundleContext {
sketcherService: SketcherService;
}
export const outputContextSpec: ContextSpec<SketcherBundleContext> = {
sketcherService: 'required'
}
export const BundleName = "@Sketcher";

View file

@ -88,6 +88,4 @@ export interface StorageBundleContext {
storageService: StorageService;
}
export const outputContextSpec: ContextSpec<StorageBundleContext> = {
storageService: 'required'
}
export const BundleName = "@Storage";

View file

@ -10,6 +10,8 @@ import {SelectionView} from "../dom/components/SelectionView";
import {GrSelect} from "react-icons/gr";
import {Explorer} from "cad/dom/components/Explorer";
export const BundleName = "@UIConfig";
export function activate(ctx) {
const {services, streams} = ctx;
streams.ui.controlBars.left.value = ['menu.file', 'menu.craft', 'menu.boolean', 'menu.primitives', 'menu.views', 'menu.viewModes', 'Donate', 'GitHub'];

View file

@ -3,25 +3,12 @@ import {WorkbenchService} from "cad/workbench/workbenchService";
import {CurrentWorkbenchIcon} from "cad/workbench/CurrentWorkbenchIcon";
import {Bundle} from "bundler/bundleSystem";
export interface WorkbenchBundleContext {
workbenchService: WorkbenchService;
}
export const WorkbenchBundle: Bundle<ApplicationContext, WorkbenchBundleContext> = {
deactivate(ctx: ApplicationContext & WorkbenchBundleContext) {
},
inputContextSpec: {
},
outputContextSpec: {
workbenchService: 'required'
},
export const WorkbenchBundle: Bundle<ApplicationContext> = {
activate(ctx: ApplicationContext) {
@ -40,6 +27,8 @@ export const WorkbenchBundle: Bundle<ApplicationContext, WorkbenchBundleContext>
}
}
]);
}
},
BundleName: "@Workbench",
}

View file

@ -8,29 +8,29 @@ import {Bundle} from "bundler/bundleSystem";
import {WorkbenchService} from "cad/workbench/workbenchService";
import {OperationService} from "cad/craft/operationBundle";
export interface WorkbenchesLoaderInputContext {
interface WorkbenchesLoaderActivationContext {
workbenchService: WorkbenchService,
operationService: OperationService
}
export const WorkbenchesLoaderPlugin: Bundle<WorkbenchesLoaderInputContext, {}> = {
type WorkbenchesLoaderWorkingContext = WorkbenchesLoaderActivationContext;
inputContextSpec: {
workbenchService: 'required',
operationService: 'required'
},
export const WorkbenchesLoaderBundle: Bundle<WorkbenchesLoaderWorkingContext> = {
outputContextSpec: {},
activationDependencies: [
'@Workbench', '@Operation'
],
activate(ctx) {
activate(ctx: WorkbenchesLoaderWorkingContext) {
registerCoreOperations(ctx);
WorkbenchRegistry.forEach(wConfig => ctx.workbenchService.registerWorkbench(wConfig));
ctx.workbenchService.switchToDefaultWorkbench();
}
},
BundleName: "@WorkbenchesLoader",
}
function registerCoreOperations(ctx: WorkbenchesLoaderInputContext) {
function registerCoreOperations(ctx: WorkbenchesLoaderActivationContext) {
ctx.operationService.registerOperations([
planeOperation,