Skip to content

Commit

Permalink
count rerenders
Browse files Browse the repository at this point in the history
  • Loading branch information
DamianoNaraku committed Oct 17, 2023
1 parent 9f88294 commit ffc34fa
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 52 deletions.
27 changes: 27 additions & 0 deletions src/App.scss
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
&.selected-by-me, &:has(.selected-by-me), // for some reason focus does not work?? so this is a fallback but needs to be properly fixed
&:hover, &:active, &:focus-within{ overflow: visible; }
}
[data-nodetype]{
overflow: visible !important; // todo: remove, it's just for debug to count renders
}

.GraphVertex[data-nodetype="GraphVertex"],
.Vertex[data-nodetype="Vertex"],
Expand Down Expand Up @@ -183,3 +186,27 @@ svg.hoverable {
.console-output-container div{
display: inline-block;
}

[data-countrenders]{
&::before{
content: attr(data-countrenders);
display: inline-block;
position: absolute;
z-index: 999;
bottom: calc(-35% + 15px);
right: -20px;
width: min-content;
height: min-content;
}
}
.animate-on-update-even{
animation: fade 1s forwards;
}
.animate-on-update-odd{
animation: fade 1s forwards;
}

@keyframes fade {
0% { opacity:0; }
100% { opacity:1; }
}
3 changes: 2 additions & 1 deletion src/common/UX.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ export class UX{
if (!Array.isArray(children)) return innermap(children as ReactNode, 0, [...depthIndices, 0]) as T;
return React.Children.map(children, (c: T, i3: number)=>innermap(c, i3, [...depthIndices,i3])) as T;
}
static injectProp(parentComponent: GraphElementComponent, e: ReactNode, gvidmap_useless: Dictionary<DocString<'VertexID'>, boolean>, parentnodeid: string, index: number, indices: number[]): ReactNode {
static injectProp(parentComponent: GraphElementComponent, e: ReactNode, gvidmap_useless: Dictionary<DocString<'VertexID'>, boolean>,
parentnodeid: string, index: number, indices: number[]): ReactNode {
const re: ReactElement | null = UX.ReactNodeAsElement(e);
if (!re) return e;
// @ts-ignore this
Expand Down
8 changes: 4 additions & 4 deletions src/components/collaborative/CollaborativeAttacher.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import Collaborative from './Collaborative';
import App from '../../App';
import {Action, SetRootFieldAction} from '../../joiner';
import {Action, CompositeAction, GObject, SetRootFieldAction} from '../../joiner';
import {useParams} from 'react-router-dom';
import {useEffectOnce} from 'usehooks-ts';

Expand All @@ -25,9 +25,9 @@ function CollaborativeAttacher(props: Props) {
})
});

Collaborative.client.on('pullAction', (action) => {
if(action.type === 'COMPOSITE_ACTION') for(let subAction of action.actions) delete subAction['_id'];
delete action['_id'];
Collaborative.client.on('pullAction', (action: GObject<Action & CompositeAction>) => {
if(action.type === 'COMPOSITE_ACTION') for(let subAction of action.actions) delete (subAction as GObject)['_id'];
delete action['_id']; // is it really needed to remove id?
const receivedAction = Action.fromJson(action);
receivedAction.hasFired = receivedAction.hasFired - 1;
receivedAction.fire();
Expand Down
13 changes: 10 additions & 3 deletions src/components/navbar/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, {Dispatch, ReactElement} from 'react';
import {connect} from 'react-redux';
import {DState} from '../../joiner';
import {DState, LState, SetRootFieldAction} from '../../joiner';
import File from './tabs/File';
import Edit from './tabs/Edit';
import Share from './tabs/Share';
Expand All @@ -9,6 +9,9 @@ import Logo from '../../static/img/logo.png';
import Debug from '../../static/img/debug.png';
import './style.scss';

let clickTimestamps: number[] = [];
const clicksRequired = 2;
const timeframe = 2000;
function NavbarComponent(props: AllProps) {
const debug = props.debug;

Expand All @@ -19,12 +22,16 @@ function NavbarComponent(props: AllProps) {
<Share />
<Examples />
{debug && <li className={'d-block ms-1 m-auto'}>
<img width={30} height={30} src={Debug} />
<img width={30} height={30} src={Debug} alt={"debug mode on"} />
</li>}
</ul>
<ul className={'navbar-nav ms-auto'}>
<li className={'d-block'}>
<img width={80} height={40} src={Logo} />
<img width={80} height={40} src={Logo} alt={"jjodel logo"} onClick={(e) => {
let now = Date.now();
if (now - clickTimestamps[clickTimestamps.length - clicksRequired] < timeframe) { SetRootFieldAction.new('debug', !debug); clickTimestamps = []; }
clickTimestamps.push(now);
}}/>
</li>
</ul>

Expand Down
59 changes: 15 additions & 44 deletions src/graph/graphElement/graphElement.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ let debugcount = 0;
let maxRenderCounter = Number.POSITIVE_INFINITY;
export const lightModeAllowedElements = [DModel.cname, DPackage.cname, DClass.cname, DEnumerator.cname, DObject.cname];

const countRenders = true;
@RuntimeAccessible
export class GraphElementComponent<AllProps extends AllPropss = AllPropss, GraphElementState extends GraphElementStatee = GraphElementStatee>
extends PureComponent<AllProps, GraphElementState>{
Expand Down Expand Up @@ -276,6 +277,7 @@ export class GraphElementComponent<AllProps extends AllPropss = AllPropss, Graph
}


countRenders: number;
_isMounted: boolean;
html: React.RefObject<HTMLElement | undefined>;
lastViewChanges: {t: number, vid: Pointer<DViewElement>, v: LViewElement, key?: string}[];
Expand Down Expand Up @@ -341,6 +343,7 @@ export class GraphElementComponent<AllProps extends AllPropss = AllPropss, Graph
this.lastOnUpdateChanges = []
this.stopUpdateEvents = undefined;
this._isMounted = false;
this.countRenders = 0;
this.id = GraphElementComponent.maxid++;
GraphElementComponent.all[this.id] = this;
GraphElementComponent.map[props.nodeid as Pointer<DGraphElement>] = this;
Expand All @@ -357,51 +360,9 @@ export class GraphElementComponent<AllProps extends AllPropss = AllPropss, Graph
this.select = this.select.bind(this);*/
for (let f of functionsToBind) (this as any)[f.name] = f.bind(this);
// @ts-ignore
this.state = {classes:[] as string[]};

/*
console.log('GE constructor props:', this.props);
this.setTemplateString(this.props.view, true);
/*if (false) this.setTemplateString('{colors:["rEd", "gReen", "blye"], key2:[0,2,5]}',
'() => { colors = colors.map(c=>c.toLowerCase())}',
'<div><b>GraphElement colors:</b>{colors.map( (c, i) => <li key={c} style={{color: c}}>{c}</li>)}</div>', true);*/
// this.onMountBindID();
}
/*
onMountBindID() {
/*if (!this.props.view.storeSize) {
// get position from view itself
nodeid = 'nodeof_' + this.props.data.id;
if (!store.getState().idlookup[nodeid]){
new CreateElementAction(this.createDataNode(nodeid));
} // view-indipendent fallback, i do not add view.id to node.id
} else {* /
if (this.getId()) return;
let dnode: DGraphElement = this.createDataNode(this.generateId());
new CreateElementAction(dnode);
// let nodeid: Pointer<DGraphElement, 1, 1, LGraphElement> = dnode.id;
// this.setState({nodeid} );
}
getId(): string | undefined {
return this.props.nodeid;
}
generateId(): Pointer<DGraphElement, 1, 1, LGraphElement> {
// if (this.state.nodeid) return this.state.nodeid;
let ret: string = 'nodeof_' + this.props.data.id + (this.props.view.storeSize ? '^' + this.props.view.id : '') + '^1';
const idlookup = store.getState().idlookup;
ret = U.increaseEndingNumber(ret, false, false, id => !idlookup[id]);
return ret;
this.state = {classes: [] as string[]};
}

// to override
createDataNode(id?: string): DGraphElement {
return new DGraphElement(id || this.generateId(), this);
}
*/

// constants: evalutate solo durante il primo render, può essere una funzione con effetti collaterali sul componente,
// in tal caso la si esegue e si prende il valore di ritorno.
// preRenderFunc: funzione evalutata ed eseguita sempre prima del render, ha senso solo per generare effetti collaterali sulle "costanti".
Expand Down Expand Up @@ -715,8 +676,14 @@ export class GraphElementComponent<AllProps extends AllPropss = AllPropss, Graph
// viewStyle.pointerEvents = "all";
viewStyle.order = viewStyle.zIndex = this.props.node?.zIndex;
viewStyle.display = this.props.view?.display;
let injectProps: GObject = {};
if (countRenders) {
classes.push(this.countRenders%2 ? "animate-on-update-even" : "animate-on-update-odd");
injectProps["data-countrenders"] = this.countRenders++;
}
rawRElement = React.cloneElement(rawRElement, // i'm cloning a raw html (like div) being root of the rendered view
{
...injectProps,
key: this.props.key, // this key is not safe. because the component has already been made,
// this would be the key of the first sub-component, which is always 1 so doesn't need a key (and is not even a component but a html node in 99% of cases)
// could remove it safely but i'm keeping it for debug so i can read keys as html attributes.
Expand Down Expand Up @@ -773,7 +740,11 @@ export class GraphElementComponent<AllProps extends AllPropss = AllPropss, Graph
rawRElement || rnode,
droparea
);
}
}/*
if (countRenders) return <>{[
rawRElement || rnode,
<div className={this.countRenders%2 ? "animate-on-update-even" : "animate-on-update-odd"} data-countrenders={this.countRenders++} />
]}</>/*/
return rawRElement || rnode;
}

Expand Down

0 comments on commit ffc34fa

Please sign in to comment.