Adam Shaw 7 лет назад
Родитель
Сommit
4dded36bdd
4 измененных файлов с 63 добавлено и 29 удалено
  1. 2 3
      src/agenda/SimpleTimeGrid.ts
  2. 2 3
      src/basic/SimpleDayGrid.ts
  3. 58 22
      src/common/slicing-utils.ts
  4. 1 1
      src/exports.ts

+ 2 - 3
src/agenda/SimpleTimeGrid.ts

@@ -10,7 +10,7 @@ import { intersectRanges, DateRange } from '../datelib/date-range'
 import DayTable from '../common/DayTable'
 import { DateEnv } from '../datelib/env'
 import { DateMarker, addMs } from '../datelib/marker'
-import { Slicer } from '../common/slicing-utils'
+import { Slicer, memoizeSlicer } from '../common/slicing-utils'
 import OffsetTracker from '../common/OffsetTracker'
 import { Hit } from '../interactions/HitDragging'
 
@@ -33,13 +33,12 @@ export default class SimpleTimeGrid extends DateComponent<SimpleTimeGridProps> {
   offsetTracker: OffsetTracker
 
   private buildDayRanges = reselector(buildDayRanges)
-  private slicer = new Slicer(sliceSegs)
+  private slicer = memoizeSlicer(new Slicer(sliceSegs, () => { return this.timeGrid }))
 
   constructor(context, timeGrid: TimeGrid) {
     super(context, timeGrid.el)
 
     this.timeGrid = timeGrid
-    this.slicer.component = timeGrid
   }
 
   render(props: SimpleTimeGridProps) {

+ 2 - 3
src/basic/SimpleDayGrid.ts

@@ -8,7 +8,7 @@ import DayTable from '../common/DayTable'
 import { Duration } from '../datelib/duration'
 import DateComponent from '../component/DateComponent'
 import { DateRange } from '../datelib/date-range'
-import { Slicer } from '../common/slicing-utils'
+import { Slicer, memoizeSlicer } from '../common/slicing-utils'
 import OffsetTracker from '../common/OffsetTracker'
 import { Hit } from '../interactions/HitDragging'
 
@@ -31,13 +31,12 @@ export default class SimpleDayGrid extends DateComponent<SimpleDayGridProps> {
   dayGrid: DayGrid
   offsetTracker: OffsetTracker
 
-  private slicer = new Slicer(sliceSegs)
+  private slicer = memoizeSlicer(new Slicer(sliceSegs, () => { return this.dayGrid }))
 
   constructor(context, dayGrid: DayGrid) {
     super(context, dayGrid.el)
 
     this.dayGrid = dayGrid
-    this.slicer.component = dayGrid
   }
 
   render(props: SimpleDayGridProps) {

+ 58 - 22
src/common/slicing-utils.ts

@@ -10,74 +10,103 @@ import DateComponent from '../component/DateComponent'
 import { Duration } from '../datelib/duration'
 import reselector from '../util/reselector'
 
+export type GetComponentFunc = () => DateComponent<any> // TODO: kill
+
+export function memoizeSlicer<OtherArgsType extends any[], SegType extends Seg>(
+  slicer: Slicer<OtherArgsType, SegType>
+) {
+  return {
+    businessHoursToSegs: reselector(slicer.businessHoursToSegs),
+    eventStoreToSegs: reselector(slicer.eventStoreToSegs),
+    selectionToSegs: reselector(slicer.dateSpanToCompleteSegs),
+    buildEventDrag: reselector(slicer.buildInteraction),
+    buildEventResize: reselector(slicer.buildInteraction)
+  }
+}
 
 export class Slicer<OtherArgsType extends any[], SegType extends Seg> {
 
   slice: (range: DateRange, ...otherArgs: OtherArgsType) => SegType[]
-  component: DateComponent<any> // must set after initialization. TODO: kill
-
-  businessHoursToSegs = reselector(this._businessHoursToSegs)
-  eventStoreToSegs = reselector(this._eventStoreToSegs)
-  selectionToSegs = reselector(this.dateSpanToCompleteSegs)
-  buildEventDrag = reselector(this.massageInteraction)
-  buildEventResize = reselector(this.massageInteraction)
+  getComponent: GetComponentFunc // TODO: kill
 
-  constructor(slice: (range: DateRange, ...otherArgs: OtherArgsType) => SegType[]) {
+  constructor(
+    slice: (range: DateRange, ...otherArgs: OtherArgsType) => SegType[],
+    getComponent: GetComponentFunc
+  ) {
     this.slice = slice
+    this.getComponent = getComponent
   }
 
-  private _eventStoreToSegs(eventStore: EventStore, eventUis: EventUiHash, dateProfile: DateProfile, nextDayThreshold: Duration, ...otherArgs: OtherArgsType): SegType[] {
+  eventStoreToSegs = (
+    eventStore: EventStore,
+    eventUis: EventUiHash,
+    dateProfile: DateProfile,
+    nextDayThreshold: Duration,
+    ...otherArgs: OtherArgsType
+  ): SegType[] => {
     if (!eventStore) {
       return []
     }
 
-    return this.eventRangesToSegs(
+    return this.eventRangesToCompleteSegs(
       sliceEventStore(eventStore, eventUis, dateProfile.activeRange, nextDayThreshold),
       otherArgs
     )
   }
 
-  private _businessHoursToSegs(businessHours: EventStore, dateProfile: DateProfile, nextDayThreshold: Duration, ...otherArgs: OtherArgsType): SegType[] {
+  businessHoursToSegs = (
+    businessHours: EventStore,
+    dateProfile: DateProfile,
+    nextDayThreshold: Duration,
+    ...otherArgs: OtherArgsType
+  ): SegType[] => {
     if (!businessHours) {
       return []
     }
 
-    return this.eventRangesToSegs(
+    return this.eventRangesToCompleteSegs(
       sliceBusinessHours(
         businessHours,
         dateProfile.activeRange,
         nextDayThreshold,
-        this.component.calendar
+        this.getComponent().calendar
       ),
       otherArgs
     )
   }
 
-  private dateSpanToCompleteSegs(dateSpan: DateSpan, ...otherArgs: OtherArgsType): SegType[] {
-
+  dateSpanToCompleteSegs = (
+    dateSpan: DateSpan,
+    ...otherArgs: OtherArgsType
+  ): SegType[] => {
     if (!dateSpan) {
       return []
     }
 
-    let eventRange = fabricateEventRange(dateSpan, this.component.calendar)
+    let component = this.getComponent()
+    let eventRange = fabricateEventRange(dateSpan, component.calendar)
     let segs = this.dateSpanToSegs(dateSpan, otherArgs)
 
     for (let seg of segs) {
-      seg.component = this.component
+      seg.component = component
       seg.eventRange = eventRange
     }
 
     return segs
   }
 
-  private massageInteraction(interaction: EventInteractionUiState, dateProfile: DateProfile, nextDayThreshold: Duration, ...otherArgs: OtherArgsType): EventSegUiInteractionState {
-
+  buildInteraction = (
+    interaction: EventInteractionUiState,
+    dateProfile: DateProfile,
+    nextDayThreshold: Duration,
+    ...otherArgs: OtherArgsType
+  ): EventSegUiInteractionState => {
     if (!interaction) {
       return null
     }
 
     return {
-      segs: this.eventRangesToSegs(
+      segs: this.eventRangesToCompleteSegs(
         sliceEventStore(interaction.mutatedEvents, interaction.eventUis, dateProfile.activeRange, nextDayThreshold),
         otherArgs
       ),
@@ -87,7 +116,10 @@ export class Slicer<OtherArgsType extends any[], SegType extends Seg> {
     }
   }
 
-  private eventRangesToSegs(eventRanges: EventRenderRange[], otherArgs: OtherArgsType): SegType[] {
+  /*
+  "complete" seg means it has component and eventRange
+  */
+  private eventRangesToCompleteSegs(eventRanges: EventRenderRange[], otherArgs: OtherArgsType): SegType[] {
     let segs: SegType[] = []
 
     for (let eventRange of eventRanges) {
@@ -97,11 +129,15 @@ export class Slicer<OtherArgsType extends any[], SegType extends Seg> {
     return segs
   }
 
+  /*
+  "complete" seg means it has component and eventRange
+  */
   private eventRangeToCompleteSegs(eventRange: EventRenderRange, otherArgs: OtherArgsType): SegType[] {
+    let component = this.getComponent()
     let segs = this.eventRangeToSegs(eventRange, otherArgs)
 
     for (let seg of segs) {
-      seg.component = this.component
+      seg.component = component
       seg.eventRange = eventRange
       seg.isStart = eventRange.isStart && seg.isStart
       seg.isEnd = eventRange.isEnd && seg.isEnd

+ 1 - 1
src/exports.ts

@@ -158,6 +158,6 @@ export { EventRenderRange, sliceEventStore } from './component/event-rendering'
 
 export { default as DayTable, DayTableSeg, DayTableCell } from './common/DayTable'
 
-export { Slicer } from './common/slicing-utils'
+export { Slicer, memoizeSlicer } from './common/slicing-utils'
 
 export { EventMutation } from './structs/event-mutation'