Skip to content

Commit

Permalink
slicer uses object for other args
Browse files Browse the repository at this point in the history
  • Loading branch information
arshaw committed Dec 4, 2018
1 parent fc4267b commit c80e117
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 52 deletions.
25 changes: 16 additions & 9 deletions src/agenda/SimpleTimeGrid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,19 @@ export interface SimpleTimeGridProps {
eventResize: EventInteractionUiState | null
}

interface SlicerArgs {
component: TimeGrid // TODO: kill
dayRanges: DateRange[]
}

export default class SimpleTimeGrid extends DateComponent<SimpleTimeGridProps> {

timeGrid: TimeGrid
dayRanges: DateRange[]
offsetTracker: OffsetTracker

private buildDayRanges = reselector(buildDayRanges)
private slicer = memoizeSlicer(new Slicer(sliceSegs, () => { return this.timeGrid }))
private slicer = memoizeSlicer(new Slicer(sliceSegs))

constructor(context, timeGrid: TimeGrid) {
super(context, timeGrid.el)
Expand All @@ -46,29 +51,30 @@ export default class SimpleTimeGrid extends DateComponent<SimpleTimeGridProps> {
let { dateProfile, dayTable } = props

let dayRanges = this.dayRanges = this.buildDayRanges(dayTable, dateProfile, this.dateEnv)
let segRes = slicer.eventStoreToSegs(props.eventStore, props.eventUis, dateProfile, null, dayRanges)
let slicerArgs: SlicerArgs = { dayRanges, component: this.timeGrid }
let segRes = slicer.eventStoreToSegs(props.eventStore, props.eventUis, dateProfile, null, slicerArgs)

this.timeGrid.receiveProps({
dateProfile,
cells: dayTable.cells[0],
businessHourSegs: slicer.businessHoursToSegs(props.businessHours, dateProfile, null, dayRanges),
businessHourSegs: slicer.businessHoursToSegs(props.businessHours, dateProfile, null, slicerArgs),
bgEventSegs: segRes.bg,
fgEventSegs: segRes.fg,
dateSelectionSegs: slicer.selectionToSegs(props.dateSelection, dayRanges),
dateSelectionSegs: slicer.selectionToSegs(props.dateSelection, slicerArgs),
eventSelection: props.eventSelection,
eventDrag: slicer.buildEventDrag(props.eventDrag, dateProfile, null, dayRanges),
eventResize: slicer.buildEventResize(props.eventResize, dateProfile, null, dayRanges)
eventDrag: slicer.buildEventDrag(props.eventDrag, dateProfile, null, slicerArgs),
eventResize: slicer.buildEventResize(props.eventResize, dateProfile, null, slicerArgs)
})
}

renderNowIndicator(date: DateMarker) {
renderNowIndicator(date: DateMarker) { // TODO: user slicer???
this.timeGrid.renderNowIndicator(
// seg system might be overkill, but it handles scenario where line needs to be rendered
// more than once because of columns with the same date (resources columns for example)
sliceSegs({
start: date,
end: addMs(date, 1) // protect against null range
}, this.dayRanges),
}, { dayRanges: this.dayRanges, component: this.timeGrid }),
date
)
}
Expand Down Expand Up @@ -128,7 +134,8 @@ export function buildDayRanges(dayTable: DayTable, dateProfile: DateProfile, dat
return ranges
}

export function sliceSegs(range: DateRange, dayRanges: DateRange[]): TimeGridSeg[] {
export function sliceSegs(range: DateRange, slicerArgs: SlicerArgs): TimeGridSeg[] {
let { dayRanges } = slicerArgs
let segs: TimeGridSeg[] = []

for (let col = 0; col < dayRanges.length; col++) {
Expand Down
23 changes: 16 additions & 7 deletions src/basic/SimpleDayGrid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,18 @@ export interface SimpleDayGridProps {
isRigid: boolean
}

interface SlicerArgs {
component: DayGrid // TODO: kill
dayTable: DayTable
isRtl: boolean
}

export default class SimpleDayGrid extends DateComponent<SimpleDayGridProps> {

dayGrid: DayGrid
offsetTracker: OffsetTracker

private slicer = memoizeSlicer(new Slicer(sliceSegs, () => { return this.dayGrid }))
private slicer = memoizeSlicer(new Slicer(sliceSegs))

constructor(context, dayGrid: DayGrid) {
super(context, dayGrid.el)
Expand All @@ -43,18 +49,19 @@ export default class SimpleDayGrid extends DateComponent<SimpleDayGridProps> {
let { dayGrid, slicer, isRtl } = this
let { dateProfile, dayTable, nextDayThreshold } = props

let segRes = slicer.eventStoreToSegs(props.eventStore, props.eventUis, dateProfile, nextDayThreshold, dayTable, isRtl)
let slicerArgs = { dayTable, isRtl, component: this.dayGrid }
let segRes = slicer.eventStoreToSegs(props.eventStore, props.eventUis, dateProfile, nextDayThreshold, slicerArgs)

dayGrid.receiveProps({
dateProfile,
cells: dayTable.cells,
businessHourSegs: slicer.businessHoursToSegs(props.businessHours, dateProfile, nextDayThreshold, dayTable, isRtl),
businessHourSegs: slicer.businessHoursToSegs(props.businessHours, dateProfile, nextDayThreshold, slicerArgs),
bgEventSegs: segRes.bg,
fgEventSegs: segRes.fg,
dateSelectionSegs: slicer.selectionToSegs(props.dateSelection, dayTable, isRtl),
dateSelectionSegs: slicer.selectionToSegs(props.dateSelection, slicerArgs),
eventSelection: props.eventSelection,
eventDrag: slicer.buildEventDrag(props.eventDrag, dateProfile, nextDayThreshold, dayTable, isRtl),
eventResize: slicer.buildEventResize(props.eventResize, dateProfile, nextDayThreshold, dayTable, isRtl),
eventDrag: slicer.buildEventDrag(props.eventDrag, dateProfile, nextDayThreshold, slicerArgs),
eventResize: slicer.buildEventResize(props.eventResize, dateProfile, nextDayThreshold, slicerArgs),
isRigid: props.isRigid
})
}
Expand Down Expand Up @@ -101,7 +108,9 @@ export default class SimpleDayGrid extends DateComponent<SimpleDayGridProps> {
SimpleDayGrid.prototype.isInteractable = true


export function sliceSegs(range: DateRange, dayTable: DayTable, isRtl: boolean): DayGridSeg[] {
export function sliceSegs(range: DateRange, slicerArgs: SlicerArgs): DayGridSeg[] {
let { dayTable, isRtl } = slicerArgs

return dayTable.sliceRange(range).map(function(seg) {
return {
isStart: seg.isStart,
Expand Down
69 changes: 37 additions & 32 deletions src/common/slicing-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,41 +10,46 @@ import { sliceBusinessHours } from '../structs/business-hours'
import DateComponent from '../component/DateComponent'
import { Duration } from '../datelib/duration'
import reselector from '../util/reselector'
import { isPropsEqual } from '../util/object'

export type GetComponentFunc = () => DateComponent<any> // TODO: kill

export function memoizeSlicer<OtherArgsType extends any[], SegType extends Seg>(
slicer: Slicer<OtherArgsType, SegType>
export function memoizeSlicer<
SegType extends Seg,
OtherArgsType extends { component: DateComponent<any> }, // TODO: kill component requirement
>(
slicer: Slicer<SegType, OtherArgsType>
) {
let buildInteraction = slicer.buildInteraction.bind(slicer) as typeof slicer.buildInteraction

// WARNING: important to keep these memoizer equalityfuncs up to date with the signatures of the methods below!!!
return {
businessHoursToSegs: reselector(slicer.businessHoursToSegs),
eventStoreToSegs: reselector(slicer.eventStoreToSegs),
selectionToSegs: reselector(slicer.dateSpanToCompleteSegs),
buildEventDrag: reselector(slicer.buildInteraction),
buildEventResize: reselector(slicer.buildInteraction)
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, null, null, null, isPropsEqual ]),
selectionToSegs: reselector(slicer.dateSpanToCompleteSegs.bind(slicer) as typeof slicer.dateSpanToCompleteSegs, [ null, isPropsEqual ]),
buildEventDrag: reselector(buildInteraction, [ null, null, null, isPropsEqual ]),
buildEventResize: reselector(buildInteraction, [ null, null, null, isPropsEqual ])
}
}

export class Slicer<OtherArgsType extends any[], SegType extends Seg> {
export class Slicer<
SegType extends Seg,
OtherArgsType extends { component: DateComponent<any> } // TODO: kill component requirement
> {

slice: (range: DateRange, ...otherArgs: OtherArgsType) => SegType[]
getComponent: GetComponentFunc // TODO: kill
slice: (range: DateRange, otherArgs: OtherArgsType) => SegType[]

constructor(
slice: (range: DateRange, ...otherArgs: OtherArgsType) => SegType[],
getComponent: GetComponentFunc
slice: (range: DateRange, otherArgs: OtherArgsType) => SegType[]
) {
this.slice = slice
this.getComponent = getComponent
}

eventStoreToSegs = (
eventStoreToSegs(
eventStore: EventStore,
eventUis: EventUiHash,
dateProfile: DateProfile,
nextDayThreshold: Duration,
...otherArgs: OtherArgsType
): { bg: SegType[], fg: SegType[] } => {
otherArgs: OtherArgsType
): { bg: SegType[], fg: SegType[] } {
if (eventStore) {
let rangeRes = sliceEventStore(eventStore, eventUis, dateProfile.activeRange, nextDayThreshold)

Expand All @@ -58,12 +63,12 @@ export class Slicer<OtherArgsType extends any[], SegType extends Seg> {
}
}

businessHoursToSegs = (
businessHoursToSegs (
businessHours: EventStore,
dateProfile: DateProfile,
nextDayThreshold: Duration,
...otherArgs: OtherArgsType
): SegType[] => {
otherArgs: OtherArgsType
): SegType[] {
if (!businessHours) {
return []
}
Expand All @@ -73,21 +78,21 @@ export class Slicer<OtherArgsType extends any[], SegType extends Seg> {
businessHours,
dateProfile.activeRange,
nextDayThreshold,
this.getComponent().calendar
otherArgs.component.calendar
),
otherArgs
)
}

dateSpanToCompleteSegs = (
dateSpanToCompleteSegs(
dateSpan: DateSpan,
...otherArgs: OtherArgsType
): SegType[] => {
otherArgs: OtherArgsType
): SegType[] {
if (!dateSpan) {
return []
}

let component = this.getComponent()
let component = otherArgs.component
let eventRange = fabricateEventRange(dateSpan, component.calendar)
let segs = this.dateSpanToSegs(dateSpan, otherArgs)

Expand All @@ -99,12 +104,12 @@ export class Slicer<OtherArgsType extends any[], SegType extends Seg> {
return segs
}

buildInteraction = (
buildInteraction(
interaction: EventInteractionUiState,
dateProfile: DateProfile,
nextDayThreshold: Duration,
...otherArgs: OtherArgsType
): EventSegUiInteractionState => {
otherArgs: OtherArgsType
): EventSegUiInteractionState {
if (!interaction) {
return null
}
Expand Down Expand Up @@ -136,7 +141,7 @@ export class Slicer<OtherArgsType extends any[], SegType extends Seg> {
"complete" seg means it has component and eventRange
*/
private eventRangeToCompleteSegs(eventRange: EventRenderRange, otherArgs: OtherArgsType): SegType[] {
let component = this.getComponent()
let component = otherArgs.component
let segs = this.eventRangeToSegs(eventRange, otherArgs)

for (let seg of segs) {
Expand All @@ -150,11 +155,11 @@ export class Slicer<OtherArgsType extends any[], SegType extends Seg> {
}

protected dateSpanToSegs(dateSpan: DateSpan, otherArgs: OtherArgsType): SegType[] {
return this.slice(dateSpan.range, ...otherArgs)
return this.slice(dateSpan.range, otherArgs)
}

protected eventRangeToSegs(eventRange: EventRenderRange, otherArgs: OtherArgsType): SegType[] {
return this.slice(eventRange.range, ...otherArgs)
return this.slice(eventRange.range, otherArgs)
}

}
2 changes: 1 addition & 1 deletion src/component/memoized-rendering.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export function memoizeRendering<ArgsType extends any[]>(
renderFunc: (...args: ArgsType) => void,
unrenderFunc?: (...args: ArgsType) => void,
dependencies: MemoizedRendering<any>[] = [],
equalityFuncs: EqualityFuncs = []
equalityFuncs?: EqualityFuncs
): MemoizedRendering<ArgsType> {

let dependents: MemoizedRendering<any>[] = []
Expand Down
6 changes: 3 additions & 3 deletions src/util/reselector.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { isArraysEqual } from './array'
import { isArraysEqual, EqualityFuncs } from './array'


export default function<T>(workerFunc: T): T {
export default function<T>(workerFunc: T, equalityFuncs?: EqualityFuncs): T {
let prevArgs
let prevResult

return function() {
if (!prevArgs || !isArraysEqual(prevArgs, arguments)) {
if (!prevArgs || !isArraysEqual(prevArgs, arguments, equalityFuncs)) {
prevArgs = arguments
prevResult = (workerFunc as any).apply(this, arguments)
}
Expand Down

0 comments on commit c80e117

Please sign in to comment.