Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proof of concept: base classes for options, events, interactions #93

Open
wants to merge 4 commits into
base: techdebt/imports
Choose a base branch
from

Conversation

mggower
Copy link
Collaborator

@mggower mggower commented Feb 2, 2024

nothing in here is "plugged" in to the renderer yet, but this stands as a proof of concept for some structured base classes

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am anticipating some push back against the use of interfaces over types here. When it comes to inheritance/sharing properties interfaces are by far the easier/cleaner approach. By leaning into inheritance we will be less likely to have inconsistencies in our type model

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably just my preference for functional programming over oop, but my assumption was that anything you can do w/ types you can do with interfaces. e.g.

interface X extends Y { foo: string, bar: string }
// same as
type X = Y & { foo: string, bar: string }

With the notable difference that types can express both intersections & and unions |. Typescript briefly notes the differences here, and honestly I like it that you can't mutate a type while you can mutate an interface (mutating an interface feels like a bug in waiting).

It's worth noting that the creator of Typescript also created C#. C#, like Java, is heavily oriented towards oop, but has also incorporated a lot of functional concepts on top. What if they both (and Typescript...) had just started with a simple functional pattern, avoided oop, and cut the language's surface area in half...?

import { Container, DisplayObject } from 'pixi.js'
import { RenderObjectLifecycle } from '../types'

export default abstract class RenderObject<T extends DisplayObject = DisplayObject> implements RenderObjectLifecycle {
Copy link
Collaborator Author

@mggower mggower Feb 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RenderObject

  • abstract class serves as a base for any display object in an app. i.e. Strokes, Icon, etc.
  • creates a required structure for all display objects making them easy to manage in a generic way
  • simple base methods can be overridden or enhanced in practice

import { Options, DefaultOptions, Viewport, Dimensions } from '../types/api'
import { DEFAULT_OPTIONS, isNumber } from '../utils'

export default class RendererOptions implements DefaultOptions {
Copy link
Collaborator Author

@mggower mggower Feb 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RendererOptions

  • straight forward class that manages and updates renderer options
  • automatically applies defaults
  • single instance that can be a shared as a dependency without losing reference to the object after updates

import { EventHandlers } from '../../types/api'
import { EventSystem } from 'pixi.js'

export default class ApplicationEvents {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ApplicationEvents

  • similar to RendererOptions, this class will manage and update application events
  • can also manage other properties like the EventSystem for easy access in relevant classes

import Drag from './plugins/Drag'
import Zoom from './plugins/Zoom'

export default class InteractionManager {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

InteractionManager

  • primarily for organization and usability

this:

this.renderer.dragInteraction.dragging
this.renderer.zoomInteraction.zooming
this.renderer.interactionObjectManager.mount(this.hitArea)
this.renderer.interaction

becomes this when you share the reference instead of the entire renderer:

this.interactions.isDragging
this.interactions.isZooming
this.interactions.manager.mount(this.hitArea)
this.interactions.container

import Interaction from '../Interaction'
import HitArea from '../hitArea/HitArea'

export default abstract class EventsManager extends Interaction {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EventsManager

  • will be the base class for defining things like node events, viewport events, etc.
  • simplifies the relationship between hit area + events

import { AllFederatedEventMap, Container, IHitArea } from 'pixi.js'
import RenderObject from '../../RenderObject'

export default class HitArea<T extends IHitArea = IHitArea> extends RenderObject<Container> {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HitArea

  • base class can be used on its own or extended to define a particular shape (circle, line, rect, etc.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants