State Management

State Management

Effective state management is paramount in ensuring consistent, reliable behavior across multimedia projects. In the Montagix SDK, we leverage the power of MobX to provide a robust and flexible state management solution, ensuring that every change in your application is tracked and responded to seamlessly.

Overview

State management in the Montagix SDK is intricately woven with MobX, a battle-tested state management library known for its efficiency and simplicity. By integrating MobX, the SDK offers developers a reactive way of managing and observing state changes, which in turn ensures that multimedia elements respond dynamically to user inputs or system events.

Key Characteristics

Reactive State Management

With MobX at its core, the SDK ensures that any observable state change triggers a reaction. This means that UI components or any dependent computations are automatically updated when the state they rely on changes.

Minimal Boilerplate

MobX's philosophy is to keep things simple. This translates to less boilerplate and more straightforward code, allowing developers to focus on the logic and behavior rather than the intricacies of state management.

Direct and Predictable

MobX operates on the principle of transparent functional reactive programming (TFRP). This ensures that the behavior of observables and reactions is both direct and predictable, leading to fewer unexpected behaviors and easier debugging.

Benefits

Efficient Updates

Only the components that depend on a piece of state are re-rendered when that state changes. This ensures optimal performance and minimizes unnecessary operations.

Streamlined Development

By reducing boilerplate and providing a clear way of managing state, developers can more rapidly implement features and respond to requirements.

Scalability

Whether managing the state for a small component or a complex multimedia scene, MobX's flexibility ensures that the SDK can handle projects of any scale.

Integration Friendly

Given its agnostic nature, integrating with other libraries or tools becomes a straightforward process. This makes it easier to extend the SDK's capabilities or integrate with other systems.

Example (React.js)

Set up the MobX Store

class EngineStore {
  engine: Engine = new Engine({
    resolution: [1920, 1080],
    storageProvider: new LocalStorageProvider(),
  });
 
  constructor() {
    makeAutoObservable(this);
  }
 
  getEngine() {
    return this.engine;
  }
}
 
export default new EngineStore();

Store the engine store instance in the React context

const EngineStoreContextProvider = (props: React.PropsWithChildren) => {
  return (
    <EngineStoreContext.Provider value={EngineStore}>
      {props.children}
    </EngineStoreContext.Provider>
  );
};
 
const EngineStoreContext = createContext<typeof EngineStore>(EngineStore);
 
export const useEngineStoreContext = () => useContext(EngineStoreContext);
 
export default EngineStoreContextProvider;

Use the engine store to interact with the engine

const Container = observer(() => {
  const engineStore = useEngineStoreContext();
  const engine = engineStore.getEngine();
 
  useEffect(() => {
    init();
  }, []);
 
  async function init() {
    const layer = engine.sceneGraph.createLayer();
 
    engine.text('Hello World').then((node) => {
      node.startAt = 0;
      node.duration = 1000;
      node.style.fontSize = 64;
 
      engine.sceneGraph.addClip(node, layer.id);
    });
 
    engine.image('/images/sample_image_1.jpg').then((node) => {
      node.startAt = 0;
      node.duration = 500;
 
      engine.sceneGraph.addClip(node, layer.id);
    });
 
    engine.image('/images/sample_image_2.jpg').then((node) => {
      node.startAt = 500;
      node.duration = 1000;
 
      engine.sceneGraph.addClip(node, layer.id);
    });
  }
 
  return (
    <div>
      Duration: {engine.duration}
    </div>
  );
});
 
export default Container;