mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-08 17:33:15 +01:00
185 lines
5.4 KiB
TypeScript
185 lines
5.4 KiB
TypeScript
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 {MObject, MObjectIdGenerator} from "../model/mobject";
|
|
import {indexById} from "gems/iterables";
|
|
import {ModelBundle} from "../projectManager/projectManagerBundle";
|
|
import {PartRepository} from "./partRepository";
|
|
import {initProjectService} from "../projectBundle";
|
|
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) {
|
|
|
|
//ctx.domService.contributeComponent(CatalogPartChooser);
|
|
|
|
//ctx.operationService.registerOperations([ImportPartOperation, ImportStepOperation, ImportStepFromLocalFileOperation]);
|
|
|
|
function loadDefinedCatalogs(): Promise<[CatalogCategory, PartsCatalog][]> {
|
|
|
|
return Promise.all(ctx.remotePartsService.partCatalogs.map(descriptor => loadCatalog(descriptor).then(entry => ([entry, descriptor] as [CatalogCategory, PartsCatalog])) ));
|
|
}
|
|
|
|
async function resolvePartReference(partRef: string): Promise<MObject[]> {
|
|
|
|
const splitIdx = partRef.indexOf('/');
|
|
|
|
if (splitIdx !== -1) {
|
|
|
|
const partRepoId = partRef.substring(0, splitIdx);
|
|
const partId = partRef.substring(splitIdx + 1);
|
|
const partRepository = ctx.remotePartsService.partRepositories[partRepoId];
|
|
if (!partRepository) {
|
|
throw "Can't resolve reference to part repository " + partRepoId;
|
|
}
|
|
try {
|
|
const bundle: ModelBundle = await partRepository.readPartResource(partId, 'model.json').then(res => res.json());
|
|
ctx.projectManager.importBundle(partRef, bundle);
|
|
} catch (e) {
|
|
if (!ctx.projectManager.exists(partRef)) {
|
|
throw e;
|
|
}
|
|
console.error(e);
|
|
console.warn('cannot load remote part ' + partRef + ', using cached version');
|
|
}
|
|
}
|
|
|
|
// ctx.craftService.pushContext(partRef);
|
|
const projectModel = ctx.projectManager.loadExternalProject(partRef);
|
|
|
|
// @ts-ignore add to the core context
|
|
const evalContext: ApplicationContext = {
|
|
craftEngine: ctx.services.craftEngine,
|
|
actionService: ctx.actionService,
|
|
operationService: ctx.operationService,
|
|
sketchStorageService: undefined,
|
|
storageService: undefined,
|
|
craftService: undefined,
|
|
expressionService: undefined,
|
|
projectService: undefined,
|
|
|
|
// @ts-ignore
|
|
services: {
|
|
},
|
|
streams: {}
|
|
|
|
};
|
|
|
|
initProjectService(evalContext, partRef, {});
|
|
activateStorageBundle(evalContext);
|
|
activateSketchStorageBundle(evalContext);
|
|
activateExpressionsBundle(evalContext);
|
|
activateCraftBundle(evalContext);
|
|
// @ts-ignore
|
|
activateCadRegistryBundle(evalContext);
|
|
// initProject(evalContext, partRef, {});
|
|
|
|
evalContext.expressionService.load(projectModel.expressions);
|
|
try {
|
|
MObjectIdGenerator.pushContext('');
|
|
await evalContext.craftService.runPipeline(projectModel.history, 0, projectModel.history.length - 1);
|
|
} finally {
|
|
MObjectIdGenerator.popContext();
|
|
}
|
|
const subSetId = MObjectIdGenerator.next(partRef, partRef);
|
|
const models = evalContext.craftService.models$.value;
|
|
models.forEach(model => {
|
|
model.traverse(m => m.id = subSetId + ':' + m.id);
|
|
});
|
|
return models;
|
|
}
|
|
|
|
ctx.remotePartsService = {
|
|
|
|
choosePartRequest$: stream(),
|
|
|
|
partCatalogs: [
|
|
//causes resolving on loading - must be lazy.
|
|
// WEB_CAD_ORG_COMMONS_CATALOG
|
|
],
|
|
|
|
partRepositories: indexById([
|
|
// WEB_CAD_ORG_PARTS_REPO
|
|
]),
|
|
|
|
resolvePartReference,
|
|
loadDefinedCatalogs
|
|
|
|
};
|
|
}
|
|
|
|
function loadCatalog(descriptor: PartsCatalog): Promise<CatalogCategory> {
|
|
return descriptor.repo.get(descriptor.metadataPath)
|
|
.then(r => r.json())
|
|
.then(catalog => catalog as CatalogCategory);
|
|
}
|
|
|
|
export interface PartsCatalog {
|
|
id: string;
|
|
name: string;
|
|
description: string;
|
|
icon: IconType,
|
|
repo: Repository;
|
|
metadataPath: string;
|
|
}
|
|
|
|
export interface CatalogEntry {
|
|
|
|
readonly name: string;
|
|
readonly type: string;
|
|
|
|
}
|
|
|
|
export interface CatalogPart extends CatalogEntry {
|
|
readonly id: string;
|
|
}
|
|
|
|
|
|
export interface CatalogCategory extends CatalogEntry {
|
|
entries: CatalogEntry[];
|
|
}
|
|
|
|
export class RemotePart {
|
|
|
|
readonly id: string;
|
|
readonly name: string;
|
|
readonly partRepo: PartRepository;
|
|
|
|
constructor(id: string, name: string, partRepo: PartRepository) {
|
|
this.id = id;
|
|
this.name = name;
|
|
this.partRepo = partRepo;
|
|
}
|
|
|
|
readPartResource = (resourceName: string) => {
|
|
return this.partRepo.readPartResource(this.id, resourceName);
|
|
}
|
|
}
|
|
|
|
export interface RemotePartsService {
|
|
|
|
choosePartRequest$: Emitter<ShowDialogRequest<void, CatalogPart>>;
|
|
|
|
partCatalogs: PartsCatalog[];
|
|
|
|
partRepositories: {
|
|
[id: string]: PartRepository
|
|
}
|
|
|
|
loadDefinedCatalogs: () => Promise<[CatalogCategory, PartsCatalog][]>
|
|
|
|
resolvePartReference(partId: string): Promise<MObject[]>;
|
|
}
|
|
|
|
export interface RemotePartsBundleContext {
|
|
|
|
remotePartsService: RemotePartsService;
|
|
}
|
|
|
|
export const BundleName = "@RemoteParts";
|
|
|