Merge branch 'small-player-refactoring' into dev

This commit is contained in:
Alex Kaminskii 2022-05-18 15:25:34 +02:00
commit 1f80cb4e64
16 changed files with 303 additions and 293 deletions

View file

@ -0,0 +1,23 @@
import type { Message } from './messages'
import ListWalker from './managers/ListWalker';
export const LIST_NAMES = ["redux", "mobx", "vuex", "ngrx", "graphql", "exceptions", "profiles", "longtasks"] as const;
export const INITIAL_STATE = {}
LIST_NAMES.forEach(name => {
INITIAL_STATE[`${name}ListNow`] = []
INITIAL_STATE[`${name}List`] = []
})
type ListsObject = {
[key in typeof LIST_NAMES[number]]: ListWalker<any>
}
export function initLists(): ListsObject {
const lists: Partial<ListsObject> = {};
for (var i = 0; i < LIST_NAMES.length; i++) {
lists[LIST_NAMES[i]] = new ListWalker();
}
return lists as ListsObject;
}

View file

@ -4,8 +4,6 @@ import logger from 'App/logger';
import Resource, { TYPES } from 'Types/session/resource'; // MBTODO: player types?
import { TYPES as EVENT_TYPES } from 'Types/session/event';
import Log from 'Types/session/log';
import Profile from 'Types/session/profile';
import ReduxAction from 'Types/session/reduxAction';
import { update } from '../store';
import {
@ -18,7 +16,7 @@ import StatedScreen from './StatedScreen/StatedScreen';
import ListWalker from './managers/ListWalker';
import PagesManager from './managers/PagesManager';
import MouseManager from './managers/MouseManager';
import MouseMoveManager from './managers/MouseMoveManager';
import PerformanceTrackManager from './managers/PerformanceTrackManager';
import WindowNodeCounter from './managers/WindowNodeCounter';
@ -30,16 +28,11 @@ import loadFiles from './network/loadFiles';
import { INITIAL_STATE as SUPER_INITIAL_STATE, State as SuperState } from './StatedScreen/StatedScreen';
import { INITIAL_STATE as ASSIST_INITIAL_STATE, State as AssistState } from './managers/AssistManager';
import { INITIAL_STATE as LISTS_INITIAL_STATE , LIST_NAMES, initLists } from './Lists';
import type { PerformanceChartPoint } from './managers/PerformanceTrackManager';
import type { SkipInterval } from './managers/ActivityManager';
const LIST_NAMES = ["redux", "mobx", "vuex", "ngrx", "graphql", "exceptions", "profiles", "longtasks"] as const;
const LISTS_INITIAL_STATE = {};
LIST_NAMES.forEach(name => {
LISTS_INITIAL_STATE[`${name}ListNow`] = [];
LISTS_INITIAL_STATE[`${name}List`] = [];
})
export interface State extends SuperState, AssistState {
performanceChartData: PerformanceChartPoint[],
@ -61,18 +54,6 @@ export const INITIAL_STATE: State = {
skipIntervals: [],
};
type ListsObject = {
[key in typeof LIST_NAMES[number]]: ListWalker<any> //
}
function initLists(): ListsObject {
const lists: Partial<ListsObject> = {};
for (var i = 0; i < LIST_NAMES.length; i++) {
lists[LIST_NAMES[i]] = new ListWalker();
}
return lists as ListsObject;
}
import type {
Message,
@ -97,7 +78,7 @@ export default class MessageDistributor extends StatedScreen {
private readonly resizeManager: ListWalker<SetViewportSize> = new ListWalker([]);
private readonly pagesManager: PagesManager;
private readonly mouseManager: MouseManager;
private readonly mouseMoveManager: MouseMoveManager;
private readonly assistManager: AssistManager;
private readonly scrollManager: ListWalker<SetViewportScroll> = new ListWalker();
@ -114,7 +95,7 @@ export default class MessageDistributor extends StatedScreen {
constructor(private readonly session: any /*Session*/, jwt: string, config, live: boolean) {
super();
this.pagesManager = new PagesManager(this, this.session.isMobile)
this.mouseManager = new MouseManager(this);
this.mouseMoveManager = new MouseMoveManager(this);
this.assistManager = new AssistManager(session, this, config);
this.sessionStart = this.session.startedAt;
@ -136,11 +117,11 @@ export default class MessageDistributor extends StatedScreen {
eventList.forEach(e => {
if (e.type === EVENT_TYPES.LOCATION) { //TODO type system
this.locationEventManager.add(e);
this.locationEventManager.append(e);
}
});
this.session.errors.forEach(e => {
this.lists.exceptions.add(e);
this.lists.exceptions.append(e);
});
/* === */
this.loadMessages();
@ -226,12 +207,12 @@ export default class MessageDistributor extends StatedScreen {
move(t: number, index?: number): void {
const stateToUpdate: Partial<State> = {};
/* == REFACTOR_ME == */
const lastLoadedLocationMsg = this.loadedLocationManager.moveToLast(t, index);
const lastLoadedLocationMsg = this.loadedLocationManager.moveGetLast(t, index);
if (!!lastLoadedLocationMsg) {
setListsStartTime(lastLoadedLocationMsg.time)
this.navigationStartOffset = lastLoadedLocationMsg.navigationStart - this.sessionStart;
}
const llEvent = this.locationEventManager.moveToLast(t, index);
const llEvent = this.locationEventManager.moveGetLast(t, index);
if (!!llEvent) {
if (llEvent.domContentLoadedTime != null) {
stateToUpdate.domContentLoadedTime = {
@ -250,22 +231,22 @@ export default class MessageDistributor extends StatedScreen {
}
}
/* === */
const lastLocationMsg = this.locationManager.moveToLast(t, index);
const lastLocationMsg = this.locationManager.moveGetLast(t, index);
if (!!lastLocationMsg) {
stateToUpdate.location = lastLocationMsg.url;
}
const lastConnectionInfoMsg = this.connectionInfoManger.moveToLast(t, index);
const lastConnectionInfoMsg = this.connectionInfoManger.moveGetLast(t, index);
if (!!lastConnectionInfoMsg) {
stateToUpdate.connType = lastConnectionInfoMsg.type;
stateToUpdate.connBandwidth = lastConnectionInfoMsg.downlink;
}
const lastPerformanceTrackMessage = this.performanceTrackManager.moveToLast(t, index);
const lastPerformanceTrackMessage = this.performanceTrackManager.moveGetLast(t, index);
if (!!lastPerformanceTrackMessage) {
stateToUpdate.performanceChartTime = lastPerformanceTrackMessage.time;
}
LIST_NAMES.forEach(key => {
const lastMsg = this.lists[key].moveToLast(t, key === 'exceptions' ? undefined : index);
const lastMsg = this.lists[key].moveGetLast(t, key === 'exceptions' ? undefined : index);
if (lastMsg != null) {
stateToUpdate[`${key}ListNow`] = this.lists[key].listNow;
}
@ -275,19 +256,19 @@ export default class MessageDistributor extends StatedScreen {
/* Sequence of the managers is important here */
// Preparing the size of "screen"
const lastResize = this.resizeManager.moveToLast(t, index);
const lastResize = this.resizeManager.moveGetLast(t, index);
if (!!lastResize) {
this.setSize(lastResize)
}
this.pagesManager.moveReady(t).then(() => {
const lastScroll = this.scrollManager.moveToLast(t, index);
const lastScroll = this.scrollManager.moveGetLast(t, index);
if (!!lastScroll && this.window) {
this.window.scrollTo(lastScroll.x, lastScroll.y);
}
// Moving mouse and setting :hover classes on ready view
this.mouseManager.move(t);
const lastClick = this.clickManager.moveToLast(t);
this.mouseMoveManager.move(t);
const lastClick = this.clickManager.moveGetLast(t);
if (!!lastClick && t - lastClick.time < 600) { // happend during last 600ms
this.cursor.click();
}
@ -300,7 +281,7 @@ export default class MessageDistributor extends StatedScreen {
}
}
_decodeMessage(msg, keys: Array<string>) {
private decodeMessage(msg, keys: Array<string>) {
const decoded = {};
try {
keys.forEach(key => {
@ -314,7 +295,7 @@ export default class MessageDistributor extends StatedScreen {
}
/* Binded */
distributeMessage = (msg: Message, index: number): void => {
distributeMessage(msg: Message, index: number): void {
if ([
"mouse_move",
"mouse_click",
@ -355,74 +336,72 @@ export default class MessageDistributor extends StatedScreen {
break;
/* */
case "set_page_location":
this.locationManager.add(msg);
this.locationManager.append(msg);
if (msg.navigationStart > 0) {
this.loadedLocationManager.add(msg);
this.loadedLocationManager.append(msg);
}
break;
case "set_viewport_size":
this.resizeManager.add(msg);
this.resizeManager.append(msg);
break;
case "mouse_move":
this.mouseManager.add(msg);
this.mouseMoveManager.append(msg);
break;
case "mouse_click":
this.clickManager.add(msg);
this.clickManager.append(msg);
break;
case "set_viewport_scroll":
this.scrollManager.add(msg);
this.scrollManager.append(msg);
break;
case "performance_track":
this.performanceTrackManager.add(msg);
this.performanceTrackManager.append(msg);
break;
case "set_page_visibility":
this.performanceTrackManager.handleVisibility(msg)
break;
case "connection_information":
this.connectionInfoManger.add(msg);
this.connectionInfoManger.append(msg);
break;
case "o_table":
this.decoder.set(msg.key, msg.value);
break;
case "redux":
decoded = this._decodeMessage(msg, ["state", "action"]);
decoded = this.decodeMessage(msg, ["state", "action"]);
logger.log(decoded)
if (decoded != null) {
this.lists.redux.add(decoded);
this.lists.redux.append(decoded);
}
break;
case "ng_rx":
decoded = this._decodeMessage(msg, ["state", "action"]);
decoded = this.decodeMessage(msg, ["state", "action"]);
logger.log(decoded)
if (decoded != null) {
this.lists.ngrx.add(decoded);
this.lists.ngrx.append(decoded);
}
break;
case "vuex":
decoded = this._decodeMessage(msg, ["state", "mutation"]);
decoded = this.decodeMessage(msg, ["state", "mutation"]);
logger.log(decoded)
if (decoded != null) {
this.lists.vuex.add(decoded);
this.lists.vuex.append(decoded);
}
break;
case "mob_x":
decoded = this._decodeMessage(msg, ["payload"]);
decoded = this.decodeMessage(msg, ["payload"]);
logger.log(decoded)
if (decoded != null) {
this.lists.mobx.add(decoded);
this.lists.mobx.append(decoded);
}
break;
case "graph_ql":
// @ts-ignore some hack? TODO: remove
msg.duration = 0;
this.lists.graphql.add(msg);
this.lists.graphql.append(msg);
break;
case "profiler":
this.lists.profiles.add(msg);
this.lists.profiles.append(msg);
break;
case "long_task":
this.lists.longtasks.add({
this.lists.longtasks.append({
...msg,
time: msg.timestamp - this.sessionStart,
});
@ -447,7 +426,7 @@ export default class MessageDistributor extends StatedScreen {
this.performanceTrackManager.setCurrentNodesCount(this.windowNodeCounter.count);
break;
}
this.pagesManager.add(msg);
this.pagesManager.append(msg);
break;
}
}
@ -457,7 +436,7 @@ export default class MessageDistributor extends StatedScreen {
}
getFirstMessageTime(): number {
return 0; //this.pagesManager.minTime;
return 0;
}
// TODO: clean managers?

View file

@ -27,14 +27,14 @@ export default class ActivityManager extends ListWalker<SkipInterval> {
updateAcctivity(time: number) {
if (time - this.lastActivity >= this.minInterval) {
this.add(new SkipIntervalCls(this.lastActivity, time));
this.append(new SkipIntervalCls(this.lastActivity, time));
}
this.lastActivity = time;
}
end() {
if (this.endTime - this.lastActivity >= this.minInterval) {
this.add(new SkipIntervalCls(this.lastActivity, this.endTime));
this.append(new SkipIntervalCls(this.lastActivity, this.endTime));
}
}

View file

@ -40,12 +40,12 @@ export default class DOMManager extends ListWalker<Message> {
if (!this.nodeScrollManagers[ m.id ]) {
this.nodeScrollManagers[ m.id ] = new ListWalker();
}
this.nodeScrollManagers[ m.id ].add(m);
this.nodeScrollManagers[ m.id ].append(m);
return;
//case "css_insert_rule": // || //set_css_data ???
//case "css_delete_rule":
// (m.tp === "set_node_attribute" && this.isLink[ m.id ] && m.key === "href")) {
// this.stylesManager.add(m);
// this.stylesManager.append(m);
// return;
default:
if (m.tp === "create_element_node") {
@ -62,7 +62,7 @@ export default class DOMManager extends ListWalker<Message> {
logger.log("Ignorring message: ", m)
return; // Ignoring...
}
super.add(m);
super.append(m);
}
}
@ -299,7 +299,7 @@ export default class DOMManager extends ListWalker<Message> {
moveReady(t: number): Promise<void> {
this.moveApply(t, this.applyMessage); // This function autoresets pointer if necessary (better name?)
this.nodeScrollManagers.forEach(manager => {
const msg = manager.moveToLast(t); // TODO: reset (?)
const msg = manager.moveGetLast(t); // TODO: reset (?)
if (!!msg && !!this.nl[msg.id]) {
const node = this.nl[msg.id] as HTMLElement;

View file

@ -1,26 +1,19 @@
import type { Timed } from '../messages/timed';
export default class ListWalker<T extends Timed> {
// Optimisation: #prop compiles to method that costs mor than strict property call.
_p = 0;
_list: Array<T>;
constructor(list: Array<T> = []) {
this._list = list;
}
add(m: T): void {
return this.append(m);
}
private p = 0
constructor(private _list: Array<T> = []) {}
append(m: T): void {
if (this.length > 0 && this.last && m.time < this.last.time) {
console.error("Trying to append message with the less time then the list tail: ", m);
console.error("Trying to append message with the less time then the list tail: ", m)
return
}
this._list.push(m);
}
reset(): void {
this._p = 0;
this.p = 0
}
sort(comparator): void {
@ -32,14 +25,6 @@ export default class ListWalker<T extends Timed> {
this._list.forEach(f);
}
// set pointer(p: number): void {
// if (p >= this.length || p < 0) {
// // console.error("Trying to set wrong pointer")
// return;
// }
// this._p = p;
// }
get last(): T | null {
if (this._list.length === 0) {
return null;
@ -48,17 +33,17 @@ export default class ListWalker<T extends Timed> {
}
get current(): T | null {
if (this._p === 0) {
if (this.p === 0) {
return null;
}
return this._list[ this._p - 1 ];
return this._list[ this.p - 1 ];
}
get timeNow(): number {
if (this._p === 0) {
if (this.p === 0) {
return 0;
}
return this._list[ this._p - 1 ].time;
return this._list[ this.p - 1 ].time;
}
get length(): number {
@ -79,7 +64,7 @@ export default class ListWalker<T extends Timed> {
}
get listNow(): Array<T> {
return this._list.slice(0, this._p);
return this._list.slice(0, this.p);
}
get list(): Array<T> {
@ -91,15 +76,15 @@ export default class ListWalker<T extends Timed> {
}
get countNow(): number {
return this._p;
return this.p;
}
/*
Returns last message with the time <= t.
Assumed that the current message is already handled so
if pointer doesn't cahnge <undefined> is returned.
if pointer doesn't cahnge <null> is returned.
*/
moveToLast(t: number, index?: number): T | null {
moveGetLast(t: number, index?: number): T | null {
let key: string = "time"; //TODO
let val = t;
if (index) {
@ -108,42 +93,29 @@ export default class ListWalker<T extends Timed> {
}
let changed = false;
while (this._p < this.length && this._list[this._p][key] <= val) {
this._p++;
while (this.p < this.length && this._list[this.p][key] <= val) {
this.p++;
changed = true;
}
while (this._p > 0 && this._list[ this._p - 1 ][key] > val) {
this._p--;
while (this.p > 0 && this._list[ this.p - 1 ][key] > val) {
this.p--;
changed = true;
}
return changed ? this._list[ this._p - 1 ] : null;
return changed ? this._list[ this.p - 1 ] : null;
}
// moveToLastByIndex(i: number): ?T {
// let changed = false;
// while (!!this._list[this._p] && this._list[this._p]._index <= i) {
// this._p++;
// changed = true;
// }
// while (this._p > 0 && this._list[ this._p - 1 ]._index > i) {
// this._p--;
// changed = true;
// }
// return changed ? this._list[ this._p - 1 ] : undefined;
// }
moveApply(t: number, fn: (T) => void): void {
moveApply(t: number, fn: (T) => void, fnBack?: (T) => void): void {
// Applying only in increment order for now
if (t < this.timeNow) {
this.reset();
}
while (!!this._list[this._p] && this._list[this._p].time <= t) {
fn(this._list[ this._p++ ]);
while (!!this._list[this.p] && this._list[this.p].time <= t) {
fn(this._list[ this.p++ ]);
}
while (fnBack && this.p > 0 && this._list[ this.p - 1 ].time > t) {
fnBack(this._list[ --this.p ]);
}
//while (this._p > 0 && this._list[ this._p - 1 ].time > t) {
// fnBack(this._list[ --this._p ]);
//}
}
}

View file

@ -1,14 +0,0 @@
// import type { MobX } from '../messages';
// import type { Timed } from '../Timed';
// import ListWalker from './ListWalker';
// type MobXTimed = MobX & Timed;
// export default class MobXStateManager extends ListWalker<MobXTimed> {
// moveToLast(t: number) {
// super.moveApply(t, )
// }
// }

View file

@ -6,10 +6,10 @@ import ListWalker from './ListWalker';
const HOVER_CLASS = "-openreplay-hover";
const HOVER_CLASS_DEPR = "-asayer-hover";
export default class MouseManager extends ListWalker<MouseMove> {
export default class MouseMoveManager extends ListWalker<MouseMove> {
private hoverElements: Array<Element> = [];
constructor(private screen: StatedScreen) {super();}
constructor(private screen: StatedScreen) {super()}
private updateHover(): void {
// @ts-ignore TODO
@ -32,7 +32,7 @@ export default class MouseManager extends ListWalker<MouseMove> {
}
move(t: number) {
const lastMouseMove = this.moveToLast(t);
const lastMouseMove = this.moveGetLast(t);
if (!!lastMouseMove){
this.screen.cursor.move(lastMouseMove);
//window.getComputedStyle(this.screen.getCursorTarget()).cursor === 'pointer' // might nfluence performance though

View file

@ -1,53 +0,0 @@
//@flow
import type StatedScreen from '../StatedScreen';
import type { Message } from '../messages';
import type { Timed } from '../Timed';
import ListWalker from './ListWalker';
import DOMManager from './DOMManager';
type TimedMessage = Timed & Message;
export default class PagesManager extends ListWalker<TimedMessage> {
#currentPage: DOMManager;
#isMobile: boolean;
#screen: StatedScreen;
constructor(screen: StatedScreen, isMobile: boolean): void {
super();
this.#screen = screen;
this.#isMobile = isMobile;
}
/*
Assumed that messages added in a correct time sequence.
*/
add(m: TimedMessage): void {
if (m.tp === "create_document") {
super.add(new DOMManager(this.#screen, this.#isMobile, m.time))
}
if (this.last === null) {
// Log wrong
return;
}
this.last.add(m);
}
sort(comparator) {
this.forEach(page => page.sort(comparator))
}
moveReady(t: number): Promise<void> {
const requiredPage = this.moveToLast(t);
if (!!requiredPage) {
this.#currentPage = requiredPage;
this.#currentPage.reset(); // Otherwise it won't apply create_document
}
if (!!this.#currentPage) {
return this.#currentPage.moveReady(t);
}
return Promise.resolve();
}
}

View file

@ -0,0 +1,50 @@
import type StatedScreen from '../StatedScreen';
import type { Message } from '../messages';
import ListWalker from './ListWalker';
import DOMManager from './DOMManager';
export default class PagesManager extends ListWalker<DOMManager> {
private currentPage: DOMManager | null = null
private isMobile: boolean;
private screen: StatedScreen;
constructor(screen: StatedScreen, isMobile: boolean) {
super()
this.screen = screen
this.isMobile = isMobile
}
/*
Assumed that messages added in a correct time sequence.
*/
add(m: Message): void {
if (m.tp === "create_document") {
super.append(new DOMManager(this.screen, this.isMobile, m.time))
}
if (this.last === null) {
// Log wrong
return;
}
this.last.append(m)
}
sort(comparator) {
this.forEach(page => page.sort(comparator))
}
moveReady(t: number): Promise<void> {
const requiredPage = this.moveGetLast(t)
if (requiredPage != null) {
this.currentPage = requiredPage
this.currentPage.reset() // Otherwise it won't apply create_document
}
if (this.currentPage != null) {
return this.currentPage.moveReady(t)
}
return Promise.resolve()
}
}

View file

@ -62,7 +62,7 @@ export default class PerformanceTrackManager extends ListWalker<PerformanceTrack
time: msg.time,
nodesCount: this.prevNodesCount,
});
super.add(msg);
super.append(msg);
}
setCurrentNodesCount(count: number) {

View file

@ -0,0 +1,53 @@
import { applyChange, revertChange } from 'deep-diff';
import ListWalker from './ListWalker';
import type { Redux } from '../messages';
export default class ReduxStateManager extends ListWalker<Redux> {
private state: Object = {}
private finalStates: Object[] = []
moveWasUpdated(time, index) {
super.moveApply(
time,
this.onIncrement,
this.onDecrement,
)
}
onIncrement = (item) => {
this.processRedux(item, true);
}
onDecrement = (item) => {
this.processRedux(item, false);
}
private processRedux(action, forward) {
if (forward) {
if (!!action.state) {
this.finalStates.push(this.state);
this.state = JSON.parse(JSON.stringify(action.state)); // Deep clone :(
} else {
action.diff.forEach(d => {
try {
applyChange(this.state, d);
} catch (e) {
//console.warn("Deepdiff error")
}
});
}
} else {
if (!!action.state) {
this.state = this.finalStates.pop();
} else {
action.diff.forEach(d => {
try {
revertChange(this.state, 1, d); // bad lib :( TODO: write our own diff
} catch (e) {
//console.warn("Deepdiff error")
}
});
}
}
}
}

View file

@ -1,96 +0,0 @@
// @flow
class NodeCounter {
_id: number;
_parent: NodeCount | null = null;
_count: number = 0;
_children: Array<NodeCounter> = [];
bubbleCount(count: number) {
this._count += count;
if (this._parent != null) {
this._parent.bubbleCount(count);
}
}
newChild(): NodeCounter {
const child = new NodeCounter();
this._children.push(child);
child._parent = this;
this.bubbleCount(1);
return child
}
removeChild(child: NodeCounter) {
this._children = this._children.filter(c => c != child);
this.bubbleCount(-(child._count + 1));
}
removeNode() {
this._parent.removeChild(this);
this._parent = null;
}
moveNode(newParent: NodeCounter) {
this.removeNode();
newParent._children.push(this);
this._parent = newParent;
newParent.bubbleCount(this._count + 1);
}
get count() {
return this._count;
}
}
export default class WindowNodeCounter {
_root: NodeCounter = new NodeCounter();
_nodes: Array<NodeCounter> = [ this._root ];
reset() {
this._root = new NodeCounter();
this._nodes = [ this._root ];
}
addNode(id: number, parentID: number) {
if (!this._nodes[ parentID ]) {
//TODO: iframe case
//console.error(`Wrong! Node with id ${ parentID } (parentId) not found.`);
return;
}
if (!!this._nodes[ id ]) {
//console.error(`Wrong! Node with id ${ id } already exists.`);
return;
}
this._nodes[id] = this._nodes[ parentID ].newChild();
}
removeNode(id: number) {
if (!this._nodes[ id ]) {
// Might be text node
//console.error(`Wrong! Node with id ${ id } not found.`);
return;
}
this._nodes[ id ].removeNode();
}
moveNode(id: number, parentId: number) {
if (!this._nodes[ id ]) {
console.error(`Wrong! Node with id ${ id } not found.`);
return;
}
if (!this._nodes[ parentId ]) {
console.error(`Wrong! Node with id ${ parentId } (parentId) not found.`);
return;
}
this._nodes[ id ].moveNode(this._nodes[ parentId ]);
}
get count() {
return this._root.count;
}
}

View file

@ -0,0 +1,96 @@
class NodeCounter {
private parent: NodeCounter | null = null
private _count: number = 0
private children: Array<NodeCounter> = []
bubbleCount(count: number) {
this._count += count
if (this.parent != null) {
this.parent.bubbleCount(count)
}
}
newChild(): NodeCounter {
const child = new NodeCounter()
this.children.push(child)
child.parent = this
this.bubbleCount(1)
return child
}
removeChild(child: NodeCounter) {
this.children = this.children.filter(c => c != child)
this.bubbleCount(-(child._count + 1))
}
removeNode() {
if (this.parent) {
this.parent.removeChild(this)
}
this.parent = null
}
moveNode(newParent: NodeCounter) {
this.removeNode()
newParent.children.push(this)
this.parent = newParent
newParent.bubbleCount(this._count + 1)
}
get count() {
return this._count
}
}
export default class WindowNodeCounter {
private root: NodeCounter = new NodeCounter()
private nodes: Array<NodeCounter> = [ this.root ]
reset() {
this.root = new NodeCounter()
this.nodes = [ this.root ]
}
addNode(id: number, parentID: number) {
if (!this.nodes[ parentID ]) {
//TODO: iframe case
//console.error(`Wrong! Node with id ${ parentID } (parentId) not found.`);
return
}
if (!!this.nodes[ id ]) {
//console.error(`Wrong! Node with id ${ id } already exists.`);
return
}
this.nodes[id] = this.nodes[ parentID ].newChild()
}
removeNode(id: number) {
if (!this.nodes[ id ]) {
// Might be text node
//console.error(`Wrong! Node with id ${ id } not found.`);
return
}
this.nodes[ id ].removeNode()
}
moveNode(id: number, parentId: number) {
if (!this.nodes[ id ]) {
console.error(`Wrong! Node with id ${ id } not found.`)
return
}
if (!this.nodes[ parentId ]) {
console.error(`Wrong! Node with id ${ parentId } (parentId) not found.`)
return
}
this.nodes[ id ].moveNode(this.nodes[ parentId ])
}
get count() {
return this.root.count
}
}

View file

@ -80,7 +80,7 @@ export default class ImagePlayer {
logger.error(e);
}
});
Object.values(this.lists).forEach(list => list.moveToLast(0)); // In case of negative values
Object.values(this.lists).forEach(list => list.moveGetLast(0)); // In case of negative values
})
if (session.socket == null || typeof session.socket.jwt !== "string" || typeof session.socket.url !== "string") {
@ -190,8 +190,8 @@ export default class ImagePlayer {
_setTime(ts) {
ts = Math.max(Math.min(ts, this.state.endTime), 0);
this.state.setTime(ts);
Object.values(this.lists).forEach(list => list.moveToLast(ts));
const screen = this._screens.moveToLast(ts);
Object.values(this.lists).forEach(list => list.moveGetLast(ts));
const screen = this._screens.moveGetLast(ts);
if (screen != null) {
const { dataURL, width, height } = screen;
this.state.setSize(width, height);
@ -199,7 +199,7 @@ export default class ImagePlayer {
//this._screen.style.backgroundImage = `url(${screen.dataURL})`;
screen.loadImage.then(() => this._screen.style.backgroundImage = `url(${screen.dataURL})`);
}
const lastClick = this._clicks.moveToLast(ts);
const lastClick = this._clicks.moveGetLast(ts);
if (lastClick != null && lastClick.time > ts - 600) {
this._animateClick(lastClick);
}

View file

@ -27,8 +27,8 @@ export default class PerformanceList {
return this._list.count;
}
moveToLast(t) {
this._list.moveToLast(t);
moveGetLast(t) {
this._list.moveGetLast(t);
}
append(m) {

View file

@ -34,8 +34,8 @@ export default class ScreenList {
this._walker._list.splice(p, 0, m);
}
moveToLast(time) {
return this._walker.moveToLast(time);
moveGetLast(time) {
return this._walker.moveGetLast(time);
}
insertScreen(time, width, height, arrayBuffer): void {