느슨하게 결합된 코드: Babylon 대 Three.js

안녕하세요! :)

얼마 전에 JavaScript에서 Three.js으로 AssemblyScript의 포트를 시작했습니다(굉장한 TypeScript에서 WebAssembly 컴파일러로).


루메 / 유리


AssemblyScript를 사용한 WebAssembly의 WebGL







유리


AssemblyScript를 사용하는 WebAssembly의 WebGL.

This is a work-in-progress port of Three.js, a JavaScript 3D WebGL library, into AssemblyScript.


동기 부여


다음을 통해 웹에서 실행되는 고성능 WebGL 엔진이 있으면 좋을 것입니다.
WebAssembly는 웹 개발자가 이미 사용하고 있는 언어로 작성되었습니다.
익숙한
JavaScript
TypeScript의 형태로 (a
유형이 포함된 JavaScript의 상위 집합).
AssemblyScript을 입력하십시오.
엄격한 형식의 하위 집합을 작성할 수 있는 도구 모음
TypeScript 코딩 및 컴파일
WebAssembly (
assembly 유사 언어
기계 코드를 나타내는) 속도를 위해.

상태



⚠️ 알파 상태


이 프로젝트는 현재 초기 알파 단계에 있습니다. 우리는 놀라운
이니셜을 구축하는 프로그래머 그룹
ASWebGLue 라이브러리. 이 라이브러리는
브라우저의 기본 WebGL 인터페이스를 호출하는 AssemblyScript 프로그램. 이것
화면에 무엇이든 렌더링하기 전에 필요합니다. ㅏ…

View on GitHub

저는 원래 포팅Babylon에 관심이 있었는데 이미 TypeScript로 작성되어 있어서 TypeScript가 처리할 수 없는 동적 부분을 리팩토링한 후 JavaScript 코드베이스를 가져와 유형을 추가하는 것보다 포팅이 더 쉬울 것입니다.

그러나 Babylon 클래스를 포팅하기 시작했을 때 라이브러리의 클래스가 밀접하게 결합되어 있음을 곧 깨달았습니다. Babylon의Scene 클래스를 가져오는 것은 사실상 전체 Babylon 라이브러리를 가져오고 라이브러리의 많은 부분(new This, new That을 인스턴스화하는 것을 의미합니다. ) 등) 해당 부분이 애플리케이션에서 사용되지 않는 경우에도 마찬가지입니다.

기본적으로 바빌론에서는 바나나(f.e.Scene)를 원하고 고릴라와 전체 정글(나머지 바빌론 라이브러리)을 얻습니다.

High coupling is something to be avoided when possible. .

Babylon의 코드베이스와 관련하여 이 문제를 이해하려면 Babylon의 import 문 scene.ts 을 살펴보십시오.

import { Nullable } from "./types";
import { Tools } from "./Misc/tools";
import { IAnimatable } from './Animations/animatable.interface';
import { PrecisionDate } from "./Misc/precisionDate";
import { Observable, Observer } from "./Misc/observable";
import { SmartArrayNoDuplicate, SmartArray, ISmartArrayLike } from "./Misc/smartArray";
import { StringDictionary } from "./Misc/stringDictionary";
import { Tags } from "./Misc/tags";
import { Vector2, Vector3, Matrix, TmpVectors, Vector4 } from "./Maths/math.vector";
import { Geometry } from "./Meshes/geometry";
import { TransformNode } from "./Meshes/transformNode";
import { SubMesh } from "./Meshes/subMesh";
import { AbstractMesh } from "./Meshes/abstractMesh";
import { Mesh } from "./Meshes/mesh";
import { IParticleSystem } from "./Particles/IParticleSystem";
import { Bone } from "./Bones/bone";
import { Skeleton } from "./Bones/skeleton";
import { MorphTargetManager } from "./Morph/morphTargetManager";
import { Camera } from "./Cameras/camera";
import { AbstractScene } from "./abstractScene";
import { BaseTexture } from "./Materials/Textures/baseTexture";
import { Texture } from "./Materials/Textures/texture";
import { RenderTargetTexture } from "./Materials/Textures/renderTargetTexture";
import { ImageProcessingConfiguration } from "./Materials/imageProcessingConfiguration";
import { Effect } from "./Materials/effect";
import { UniformBuffer } from "./Materials/uniformBuffer";
import { MultiMaterial } from "./Materials/multiMaterial";
import { Light } from "./Lights/light";
import { PickingInfo } from "./Collisions/pickingInfo";
import { ICollisionCoordinator } from "./Collisions/collisionCoordinator";
import { PointerEventTypes, PointerInfoPre, PointerInfo } from "./Events/pointerEvents";
import { KeyboardInfoPre, KeyboardInfo } from "./Events/keyboardEvents";
import { ActionEvent } from "./Actions/actionEvent";
import { PostProcessManager } from "./PostProcesses/postProcessManager";
import { IOfflineProvider } from "./Offline/IOfflineProvider";
import { RenderingGroupInfo, RenderingManager, IRenderingManagerAutoClearSetup } from "./Rendering/renderingManager";
import { ISceneComponent, ISceneSerializableComponent, Stage, SimpleStageAction, RenderTargetsStageAction, RenderTargetStageAction, MeshStageAction, EvaluateSubMeshStageAction, PreActiveMeshStageAction, CameraStageAction, RenderingGroupStageAction, RenderingMeshStageAction, PointerMoveStageAction, PointerUpDownStageAction, CameraStageFrameBufferAction } from "./sceneComponent";
import { Engine } from "./Engines/engine";
import { Node } from "./node";
import { MorphTarget } from "./Morph/morphTarget";
import { Constants } from "./Engines/constants";
import { DomManagement } from "./Misc/domManagement";
import { Logger } from "./Misc/logger";
import { EngineStore } from "./Engines/engineStore";
import { AbstractActionManager } from './Actions/abstractActionManager';
import { _DevTools } from './Misc/devTools';
import { WebRequest } from './Misc/webRequest';
import { InputManager } from './Inputs/scene.inputManager';
import { PerfCounter } from './Misc/perfCounter';
import { IFileRequest } from './Misc/fileRequest';
import { Color4, Color3 } from './Maths/math.color';
import { Plane } from './Maths/math.plane';
import { Frustum } from './Maths/math.frustum';
import { UniqueIdGenerator } from './Misc/uniqueIdGenerator';
import { FileTools, LoadFileError, RequestFileError, ReadFileError } from './Misc/fileTools';
import { IClipPlanesHolder } from './Misc/interfaces/iClipPlanesHolder';
import { IPointerEvent } from "./Events/deviceInputEvents";
import { WebVRFreeCamera } from "./Cameras/VR/webVRCamera";


"장면"이 나타내는 항목에 대한 상당히 긴 목록이며 스크롤하지 않고도 내 컴퓨터 화면에서 전체 목록을 볼 수 있습니다.

반대로 Three.js 코드베이스는 훨씬 더 느슨하게 결합되어 있어 코드 저작 관점에서 매우 매력적입니다. 그래서 저는 결국 Three.js를 선택하고 TypeScript 대신 JavaScript에서 더 많은 포팅을 수행할 것이라는 점을 받아들였습니다. 나는 최종 결과가 더 깨끗할 것이라고 느꼈다.

Three's Lose Coupling의 예로서 다음은 Three's Scene.js 의 처음 몇 줄입니다.

import { Object3D } from '../core/Object3D.js';

class Scene extends Object3D {

    constructor() {

        super();

        this.type = 'Scene';

        this.background = null;
        this.environment = null;
        this.fog = null;


Three의 코드 기반을 탐색하면 클래스가 최소화되고 한 가지만 잘 수행(또는 한 개념만 잘 표현)하는 것을 볼 수 있습니다.

Babylon을 사용하여 포팅을 시작한 후 Three.js로 돌아가는 것은 느슨한 결합으로 인해 기분이 좋았습니다. Three.js 코드베이스는 깨끗합니다.

하나의 코드베이스 또는 다른 코드베이스에서 개발하거나 확장해야 하는 경우 Three.js를 선택할 것입니다. 라이브러리 내의 느슨하게 결합된 조직이 코드 유지 관리 및 확장을 더 쉽게 만들고 Three 라이브러리의 특정 부분을 허용하기 때문입니다. 불필요한 종속성을 애플리케이션으로 가져오지 않고 사용할 수 있습니다.


Babylon 커뮤니티에 다른 누군가가 Babylon의 부분이 예를 들어 Three.js와 비교하여 너무 밀접하게 결합되어 있다고 느끼는지 묻고 싶었지만 내 게시물은 즉시 "스팸"으로 숨겨졌습니다.

https://forum.babylonjs.com/t/high-coupling-in-the-bablyon-codebase-compared-to-three-js/21156/3

(영구적으로 삭제하면 보이지 않을 수도 있습니다.)

그 스레드에서 나는 물었다.

Has anyone else (especially on Bablyon’s team) thought about this difference between Babylon and Three.js? What are your thoughts on this? Are there any plans or desires to decouple the Babylon code base?



나는 이 주제에 대한 토론을 시작하기를 바랐고, 그것이 모두의 이익을 위해 바빌론 개선에 불을 붙일 수 있기를 바랐습니다(대안을 갖는 것은 항상 좋은 일입니다).

좋은 웹페이지 즐겨찾기