Jelajahi Sumber

dont pass around eventUiBySource, smarter about memoizing eventUiBases

Adam Shaw 7 tahun lalu
induk
melakukan
4ad45e0073

+ 34 - 12
src/Calendar.ts

@@ -15,16 +15,16 @@ import { Duration, createDuration } from './datelib/duration'
 import reduce from './reducers/main'
 import { parseDateSpan, DateSpanInput, DateSpan, buildDateSpanApi, DateSpanApi, buildDatePointApi, DatePointApi } from './structs/date-span'
 import reselector from './util/reselector'
-import { mapHash, assignTo } from './util/object'
+import { mapHash, assignTo, isPropsEqual } from './util/object'
 import { DateRangeInput } from './datelib/date-range'
 import DateProfileGenerator from './DateProfileGenerator'
 import { EventSourceInput, parseEventSource } from './structs/event-source'
-import { EventInput, parseEvent } from './structs/event'
+import { EventInput, parseEvent, EventDefHash } from './structs/event'
 import { CalendarState, Action } from './reducers/types'
 import EventSourceApi from './api/EventSourceApi'
 import EventApi from './api/EventApi'
 import { createEmptyEventStore, EventStore, eventTupleToStore } from './structs/event-store'
-import { processScopedUiProps, EventUiHash } from './component/event-ui'
+import { processScopedUiProps, EventUiHash, EventUi } from './component/event-ui'
 import PointerDragging, { PointerDragEvent } from './dnd/PointerDragging'
 import EventDragging from './interactions/EventDragging'
 import { buildViewSpecs, ViewSpecHash, ViewSpec } from './structs/view-spec'
@@ -63,10 +63,10 @@ export default class Calendar {
   triggerWith: EmitterInterface['triggerWith']
   hasHandlers: EmitterInterface['hasHandlers']
 
-  buildDateEnv = reselector(buildDateEnv)
-  buildTheme = reselector(buildTheme)
-  buildEventUiBase = reselector(processScopedUiProps)
+  private buildDateEnv = reselector(buildDateEnv)
+  private buildTheme = reselector(buildTheme)
 
+  // strictly for constraint system
   eventUiBases: EventUiHash
   renderableEventUis: EventUiHash
 
@@ -404,14 +404,13 @@ export default class Calendar {
         this.renderableEventStore :
         state.eventStore
 
-    let eventUiBases = this.eventUiBases = { '': this.buildEventUiBase(viewSpec.options, this) }
-    let eventUiBySource = mapHash(state.eventSources, (eventSource) => eventSource.ui)
+    let eventUiSingleBase = this.buildEventUiSingleBase(viewSpec.options, this)
+    let eventUiBySource: EventUiHash = mapHash(state.eventSources, (eventSource) => eventSource.ui)
+    let eventUiBases = this.eventUiBases = this.buildEventUiBases(renderableEventStore.defs, eventUiSingleBase, eventUiBySource)
 
-    // specifically for validation system
     this.renderableEventUis = compileEventUis(
       renderableEventStore.defs,
-      eventUiBases,
-      eventUiBySource
+      eventUiBases
     )
 
     if (needsFull || !component) {
@@ -436,7 +435,6 @@ export default class Calendar {
         dateProfileGenerator: this.dateProfileGenerators[viewType],
         eventStore: renderableEventStore,
         eventUiBases,
-        eventUiBySource,
         dateSelection: state.dateSelection,
         eventSelection: state.eventSelection,
         eventDrag: state.eventDrag,
@@ -476,6 +474,30 @@ export default class Calendar {
   }
 
 
+  private buildEventUiSingleBase = reselector(processScopedUiProps)
+
+  private buildEventUiBases = reselector(function(
+    eventDefs: EventDefHash,
+    eventUiSingleBase: EventUi,
+    eventUiBySource: EventUiHash
+  ) {
+    let eventUiBases: EventUiHash = { '': eventUiSingleBase }
+
+    for (let defId in eventDefs) {
+      let def = eventDefs[defId]
+
+      if (def.sourceId && eventUiBySource[def.sourceId]) {
+        eventUiBases[defId] = eventUiBySource[def.sourceId]
+      }
+    }
+
+    return eventUiBases
+  }, [
+    // equality funcs. KEEP UP TO DATE with method signature!
+    null, null, isPropsEqual
+  ])
+
+
   // Options
   // -----------------------------------------------------------------------------------------------------------------
 

+ 0 - 2
src/CalendarComponent.ts

@@ -20,7 +20,6 @@ export interface CalendarComponentProps extends CalendarState {
   viewSpec: ViewSpec
   dateProfileGenerator: DateProfileGenerator // for the current view
   eventUiBases: EventUiHash
-  eventUiBySource: EventUiHash
 }
 
 export default class CalendarComponent extends Component<CalendarComponentProps> {
@@ -183,7 +182,6 @@ export default class CalendarComponent extends Component<CalendarComponentProps>
         businessHours: this.parseBusinessHours(viewSpec.options.businessHours),
         eventStore: props.eventStore,
         eventUiBases: props.eventUiBases,
-        eventUiBySource: props.eventUiBySource,
         dateSelection: props.dateSelection,
         eventSelection: props.eventSelection,
         eventDrag: props.eventDrag,

+ 1 - 8
src/View.ts

@@ -1,4 +1,4 @@
-import { assignTo, isPropsEqual } from './util/object'
+import { assignTo } from './util/object'
 import { parseFieldSpecs } from './util/misc'
 import DateProfileGenerator, { DateProfile } from './DateProfileGenerator'
 import { DateMarker, addMs } from './datelib/marker'
@@ -20,7 +20,6 @@ export interface ViewProps {
   businessHours: EventStore
   eventStore: EventStore
   eventUiBases: EventUiHash
-  eventUiBySource: EventUiHash
   dateSelection: DateSpan | null
   eventSelection: string
   eventDrag: EventInteractionState | null
@@ -213,7 +212,6 @@ export default abstract class View extends DateComponent<ViewProps> {
     return sliceEventStore(
       eventStore,
       props.eventUiBases,
-      props.eventUiBySource,
       props.dateProfile.activeRange,
       allDay ? this.nextDayThreshold : null
     ).fg
@@ -446,8 +444,3 @@ EmitterMixin.mixInto(View)
 
 View.prototype.usesMinMaxTime = false
 View.prototype.dateProfileGeneratorClass = DateProfileGenerator
-
-View.addEqualityFuncs({
-  eventUiBases: isPropsEqual,
-  eventUiBySource: isPropsEqual
-})

+ 0 - 2
src/agenda/AgendaView.ts

@@ -82,7 +82,6 @@ export default class AgendaView extends AbstractAgendaView {
       dateSelection: dateSelection && !dateSelection.allDay ? dateSelection : null,
       eventStore: eventStores.timed,
       eventUiBases: props.eventUiBases,
-      eventUiBySource: props.eventUiBySource,
       eventSelection: props.eventSelection,
       eventDrag: eventDrags.timed,
       eventResize: eventResizes.timed
@@ -96,7 +95,6 @@ export default class AgendaView extends AbstractAgendaView {
         dateSelection: dateSelection && dateSelection.allDay ? dateSelection : null,
         eventStore: eventStores.allDay,
         eventUiBases: props.eventUiBases,
-        eventUiBySource: props.eventUiBySource,
         eventSelection: props.eventSelection,
         eventDrag: eventDrags.allDay,
         eventResize: eventResizes.allDay,

+ 2 - 4
src/agenda/SimpleTimeGrid.ts

@@ -20,7 +20,6 @@ export interface SimpleTimeGridProps {
   businessHours: EventStore
   eventStore: EventStore
   eventUiBases: EventUiHash
-  eventUiBySource: EventUiHash
   dateSelection: DateSpan | null
   eventSelection: string
   eventDrag: EventInteractionState | null
@@ -56,7 +55,6 @@ export default class SimpleTimeGrid extends DateComponent<SimpleTimeGridProps> {
     let segRes = slicer.eventStoreToSegs(
       props.eventStore,
       props.eventUiBases,
-      props.eventUiBySource,
       dateProfile,
       null,
       slicerArgs
@@ -70,8 +68,8 @@ export default class SimpleTimeGrid extends DateComponent<SimpleTimeGridProps> {
       fgEventSegs: segRes.fg,
       dateSelectionSegs: slicer.selectionToSegs(props.dateSelection, props.eventUiBases, slicerArgs),
       eventSelection: props.eventSelection,
-      eventDrag: slicer.buildEventDrag(props.eventDrag, props.eventUiBases, props.eventUiBySource, dateProfile, null, slicerArgs),
-      eventResize: slicer.buildEventResize(props.eventResize, props.eventUiBases, props.eventUiBySource, dateProfile, null, slicerArgs)
+      eventDrag: slicer.buildEventDrag(props.eventDrag, props.eventUiBases, dateProfile, null, slicerArgs),
+      eventResize: slicer.buildEventResize(props.eventResize, props.eventUiBases, dateProfile, null, slicerArgs)
     })
   }
 

+ 0 - 1
src/basic/BasicView.ts

@@ -64,7 +64,6 @@ export default class BasicView extends AbstractBasicView {
       dateSelection: props.dateSelection,
       eventStore: props.eventStore,
       eventUiBases: props.eventUiBases,
-      eventUiBySource: props.eventUiBySource,
       eventSelection: props.eventSelection,
       eventDrag: props.eventDrag,
       eventResize: props.eventResize,

+ 2 - 4
src/basic/SimpleDayGrid.ts

@@ -19,7 +19,6 @@ export interface SimpleDayGridProps {
   businessHours: EventStore
   eventStore: EventStore
   eventUiBases: EventUiHash
-  eventUiBySource: EventUiHash
   dateSelection: DateSpan | null
   eventSelection: string
   eventDrag: EventInteractionState | null
@@ -54,7 +53,6 @@ export default class SimpleDayGrid extends DateComponent<SimpleDayGridProps> {
     let segRes = slicer.eventStoreToSegs(
       props.eventStore,
       props.eventUiBases,
-      props.eventUiBySource,
       dateProfile,
       nextDayThreshold,
       slicerArgs
@@ -68,8 +66,8 @@ export default class SimpleDayGrid extends DateComponent<SimpleDayGridProps> {
       fgEventSegs: segRes.fg,
       dateSelectionSegs: slicer.selectionToSegs(props.dateSelection, props.eventUiBases, slicerArgs),
       eventSelection: props.eventSelection,
-      eventDrag: slicer.buildEventDrag(props.eventDrag, props.eventUiBases, props.eventUiBySource, dateProfile, nextDayThreshold, slicerArgs),
-      eventResize: slicer.buildEventResize(props.eventResize, props.eventUiBases, props.eventUiBySource, dateProfile, nextDayThreshold, slicerArgs),
+      eventDrag: slicer.buildEventDrag(props.eventDrag, props.eventUiBases, dateProfile, nextDayThreshold, slicerArgs),
+      eventResize: slicer.buildEventResize(props.eventResize, props.eventUiBases, dateProfile, nextDayThreshold, slicerArgs),
       isRigid: props.isRigid
     })
   }

+ 6 - 8
src/common/slicing-utils.ts

@@ -24,10 +24,10 @@ export function memoizeSlicer<
   // YUCK
   return {
     businessHoursToSegs: reselector(slicer.businessHoursToSegs.bind(slicer) as typeof slicer.businessHoursToSegs, [ null, null, null, isPropsEqual ]),
-    eventStoreToSegs: reselector(slicer.eventStoreToSegs.bind(slicer) as typeof slicer.eventStoreToSegs, [ null, isPropsEqual, isPropsEqual, null, null, isPropsEqual ]),
-    selectionToSegs: reselector(slicer.dateSpanToCompleteSegs.bind(slicer) as typeof slicer.dateSpanToCompleteSegs, [ null, isPropsEqual, isPropsEqual ]),
-    buildEventDrag: reselector(buildInteraction, [ null, isPropsEqual, isPropsEqual, null, null, isPropsEqual ]),
-    buildEventResize: reselector(buildInteraction, [ null, isPropsEqual, isPropsEqual, null, null, isPropsEqual ])
+    eventStoreToSegs: reselector(slicer.eventStoreToSegs.bind(slicer) as typeof slicer.eventStoreToSegs, [ null, isPropsEqual, null, null, isPropsEqual ]),
+    selectionToSegs: reselector(slicer.dateSpanToCompleteSegs.bind(slicer) as typeof slicer.dateSpanToCompleteSegs, [ null, isPropsEqual ]),
+    buildEventDrag: reselector(buildInteraction, [ null, isPropsEqual, null, null, isPropsEqual ]),
+    buildEventResize: reselector(buildInteraction, [ null, isPropsEqual, null, null, isPropsEqual ])
   }
 }
 
@@ -47,13 +47,12 @@ export class Slicer<
   eventStoreToSegs(
     eventStore: EventStore,
     eventUiBases: EventUiHash,
-    eventUiBySource: EventUiHash,
     dateProfile: DateProfile,
     nextDayThreshold: Duration,
     otherArgs: OtherArgsType
   ): { bg: SegType[], fg: SegType[] } {
     if (eventStore) {
-      let rangeRes = sliceEventStore(eventStore, eventUiBases, eventUiBySource, dateProfile.activeRange, nextDayThreshold)
+      let rangeRes = sliceEventStore(eventStore, eventUiBases, dateProfile.activeRange, nextDayThreshold)
 
       return {
         bg: this.eventRangesToCompleteSegs(rangeRes.bg, otherArgs),
@@ -110,7 +109,6 @@ export class Slicer<
   buildInteraction(
     interaction: EventInteractionState,
     eventUiBases: EventUiHash,
-    eventUiBySource: EventUiHash,
     dateProfile: DateProfile,
     nextDayThreshold: Duration,
     otherArgs: OtherArgsType
@@ -119,7 +117,7 @@ export class Slicer<
       return null
     }
 
-    let rangeRes = sliceEventStore(interaction.mutatedEvents, eventUiBases, eventUiBySource, dateProfile.activeRange, nextDayThreshold)
+    let rangeRes = sliceEventStore(interaction.mutatedEvents, eventUiBases, dateProfile.activeRange, nextDayThreshold)
 
     return {
       segs: this.eventRangesToCompleteSegs(rangeRes.fg, otherArgs),

+ 7 - 7
src/component/event-rendering.ts

@@ -19,13 +19,13 @@ export interface EventRenderRange extends EventTuple {
 /*
 Specifying nextDayThreshold signals that all-day ranges should be sliced.
 */
-export function sliceEventStore(eventStore: EventStore, eventUiBases: EventUiHash, eventUiBySource: EventUiHash, framingRange: DateRange, nextDayThreshold?: Duration) {
+export function sliceEventStore(eventStore: EventStore, eventUiBases: EventUiHash, framingRange: DateRange, nextDayThreshold?: Duration) {
   let inverseBgByGroupId: { [groupId: string]: DateRange[] } = {}
   let inverseBgByDefId: { [defId: string]: DateRange[] } = {}
   let defByGroupId: { [groupId: string]: EventDef } = {}
   let bgRanges: EventRenderRange[] = []
   let fgRanges: EventRenderRange[] = []
-  let eventUis = compileEventUis(eventStore.defs, eventUiBases, eventUiBySource)
+  let eventUis = compileEventUis(eventStore.defs, eventUiBases)
 
   for (let defId in eventStore.defs) {
     let def = eventStore.defs[defId]
@@ -166,21 +166,21 @@ export function getElSeg(el: HTMLElement): Seg | null {
 
 // event ui computation
 
-export function compileEventUis(eventDefs: EventDefHash, eventUiBases: EventUiHash, eventUiBySource: EventUiHash) {
+export function compileEventUis(eventDefs: EventDefHash, eventUiBases: EventUiHash) {
   return mapHash(eventDefs, function(eventDef: EventDef) {
-    return compileEventUi(eventDef, eventUiBases, eventUiBySource)
+    return compileEventUi(eventDef, eventUiBases)
   })
 }
 
-export function compileEventUi(eventDef: EventDef, eventUiBases: EventUiHash, eventUiBySource: EventUiHash) {
+export function compileEventUi(eventDef: EventDef, eventUiBases: EventUiHash) {
   let uis = []
 
   if (eventUiBases['']) {
     uis.push(eventUiBases[''])
   }
 
-  if (eventDef.sourceId && eventUiBySource[eventDef.sourceId]) {
-    uis.push(eventUiBySource[eventDef.sourceId])
+  if (eventUiBases[eventDef.defId]) {
+    uis.push(eventUiBases[eventDef.defId])
   }
 
   uis.push(eventDef.ui)

+ 1 - 2
src/interactions-external/ExternalElementDragging.ts

@@ -76,8 +76,7 @@ export default class ExternalElementDragging {
           let droppableEventStore = eventTupleToStore(droppableEvent)
           let droppableEventUis = compileEventUis(
             droppableEventStore.defs,
-            receivingCalendar.eventUiBases,
-            {} // eventUiBySource
+            receivingCalendar.eventUiBases
           )
 
           isInvalid = !isEventsValid(droppableEventStore, droppableEventUis, receivingCalendar)

+ 2 - 3
src/list/ListView.ts

@@ -64,7 +64,7 @@ export default class ListView extends View {
     this.dayDates = dayDates
 
     this.renderContent(
-      this.eventStoreToSegs(props.eventStore, props.eventUiBases, props.eventUiBySource, dayRanges)
+      this.eventStoreToSegs(props.eventStore, props.eventUiBases, dayRanges)
     )
   }
 
@@ -96,12 +96,11 @@ export default class ListView extends View {
   }
 
 
-  _eventStoreToSegs(eventStore: EventStore, eventUiBases: EventUiHash, eventUiBySource: EventUiHash, dayRanges: DateRange[]): Seg[] {
+  _eventStoreToSegs(eventStore: EventStore, eventUiBases: EventUiHash, dayRanges: DateRange[]): Seg[] {
     return this.eventRangesToSegs(
       sliceEventStore(
         eventStore,
         eventUiBases,
-        eventUiBySource,
         this.props.dateProfile.activeRange,
         this.nextDayThreshold
       ).fg,

+ 1 - 2
src/structs/business-hours.ts

@@ -63,8 +63,7 @@ export function sliceBusinessHours(businessHours: EventStore, range: DateRange,
 
   return sliceEventStore(
     expandedStore,
-    {},
-    {},
+    {}, // eventUiBases
     range,
     nextDayThreshold
   ).bg

+ 1 - 1
src/structs/date-span.ts

@@ -169,7 +169,7 @@ export function fabricateEventRange(dateSpan: DateSpan, eventUiBases: EventUiHas
 
   return {
     def,
-    ui: compileEventUi(def, eventUiBases, {}),
+    ui: compileEventUi(def, eventUiBases),
     instance: createEventInstance(def.defId, dateSpan.range),
     range: dateSpan.range,
     isStart: true,