Throttle redraw requests fired from pointer events

I am working on a photo editor, which displays a preview to the user on a canvas. At various points in the app, the user may use sliders to adjust properties of the photo, such as scaling, rotation, etc. The preview needs to be updated in real time, as the user drags the slider.

As I understand, pointer events are fired much more rapidly than the browser window is repainted. Because of this, it would be wasteful to update the preview directly from the pointer event handlers, since most of those updates would have no visible effect. Instead, I wanted to separate the actions of updating the preview state based on the most recent pointer event, and redrawing the preview based on the latest update since the last redraw.

To this end, I wrote a small helper function called throttleRedraw(), which I’d appreciate if you could review. Is it properly optimized? Is it even necessary? There’s probably a library for it, but I wanted to make sure I understand the principle at the core.

Here’s a snippet containing the function itself, and a simple example that draws a rectangle on a canvas when you click and drag with the pointer:

function throttleRedraw(target, props) {   const {     onstart,     onmove,     onend,     ondraw,     absolute,   } = props;    let frameReq = 0;   let lastX = 0;   let lastY = 0;   let isTouch = false;   let enabled = true;    // This is the callback we will be passing to requestAnimationFrame().   // It's just a proxy for the ondraw() function passed in the props object.   const frameHandler = (now) => {     if (ondraw) ondraw(now);     frameReq = 0;   };    // The callback for the mousemove/touchmove events,   // which in turn calls props.onmove() if it was specified.   // If props.absolute is true, props.onmove() receives the x and y coordinates of the pointer;   // otherwise, it receives the delta since the last update.   const moveHandler = (event) => {     if (onmove) {       const newX = isTouch ? event.touches[0].clientX : event.clientX;       const newY = isTouch ? event.touches[0].clientY : event.clientY;       onmove(         absolute ? newX : newX - lastX,         absolute ? newY : newY - lastY,         event       );       lastX = newX;       lastY = newY;     }      // If we have not yet requested an animation frame since the last, do it now.     if (!frameReq) {       frameReq = window.requestAnimationFrame(frameHandler);     }   };    // The callback for the mouseup/touchend events,   // which in turn calls props.onend() if it was specified.   const upHandler = (event) => {     if (onend) onend(event);          // Remove the event handlers we set at the start.     if (!isTouch) {       window.removeEventListener('mousemove', moveHandler);       window.removeEventListener('mouseup', upHandler);     }     else {       window.removeEventListener('touchmove', moveHandler);       window.removeEventListener('touchend', upHandler);       window.removeEventListener('touchcancel', upHandler);     }   };    // Set the mousedown/touchstart event listeners on the target.   // They're mostly the same, except for how the coordinates are obtained   // from the event, and what additional event handlers need to be set.    target.addEventListener('mousedown', (event) => {     if (!enabled) return true;      isTouch = false;     event.preventDefault();     lastX = event.clientX;     lastY = event.clientY;     if (onstart) onstart(lastX, lastY, event);      window.addEventListener('mousemove', moveHandler);     window.addEventListener('mouseup', upHandler);   });    target.addEventListener('touchstart', (event) => {     if (!enabled) return true;      isTouch = true;     event.preventDefault();     lastX = event.touches[0].clientX;     lastY = event.touches[0].clientY;     if (onstart) onstart(lastX, lastY, event);      window.addEventListener('touchmove', moveHandler);     window.addEventListener('touchend', upHandler);     window.addEventListener('touchcancel', upHandler);   });    // Return an object that allows us to enable or disable listening for events,   // and query the current enabled state.   return {     isEnabled: () => enabled,     enable: (value) => { enabled = value; },   }; }  const canvas = document.querySelector('canvas'); const rect = canvas.getBoundingClientRect(); const ctx = canvas.getContext('2d');  let x0, y0, x1, y1;  throttleRedraw(canvas, {   absolute: true,    onstart: (x, y) => {     x0 = x - rect.left;     y0 = y - rect.top;     ctx.clearRect(0, 0, canvas.width, canvas.height);     ctx.fillStyle = 'red';   },   onmove: (x, y) => {     x1 = x - rect.left;     y1 = y - rect.top;   },   ondraw: () => {     ctx.clearRect(0, 0, canvas.width, canvas.height);     ctx.fillRect(       Math.min(x0, x1),       Math.min(y0, y1),       Math.abs(x1 - x0),       Math.abs(y1 - y0)     );   }, });
<canvas width="400" height="400" style="border: 2px solid #888"></canvas>

Thanks in advance.

Tracking revision history by recording events

I’ve got a requirement to create a data structure that allows for users to view revision history. Not just the history of a table, but the history of the entire structure at a given point in time.

A pure database solution would involve massive recreation of records. For example – say I’m building a check sheet. Sheets have multiple to-do items, to-do items can be assigned to multiple sheets. It’s a simple many to many relationship.

Now say I edit the sheet to remove an item. To maintain revision history, I have to recreate the check sheet and recreate its relationship to the to-do items, minus the one that got removed. And editing a to-do item would cause me to have to recreate every check sheet that references it.

So the solution I’m thinking about is to record the actions that are performed against the check sheets, and when a user wants to specific revision, replay all the changes against an object graph in my code.

Is there an event driven data pattern out there? Is this the best way to do this? I’m just looking for input from anyone who has had to work with revision history for massive data structures before.

Questions regarding mutual independence of events

Have a few questions regarding mutual independence:

  1. If I have a set of events $ A_1, A_2, …A_n$ that are all pairwise independent, it is possible that the events may not be mutually independent?

  2. If I have n events and $ P(A_1 \cap A_2 \cap … A_n) = P(A_1)P(A_2)…P(A_n)$ , it is possible that the events are not pairwise independent (and hence not mutually independent)?

  3. If I have a sample space $ \Omega = A_1 \cup A_2 \cup … A_n $ where $ A_1, A_2, …A_n $ are all pairwise disjoint, does this mean that $ A_1, A_2, …A_n $ are also mutually independent (not just pairwise independent)?

Passing onChange events through the state

I am creating a form component and I want to be able to pass on change elements per form element and I cannot seem to get it work properly.

I have my LoginComponent

import React from "react"; import './LoginComponent.css';  import FormComponent from '../FormComponent/FormComponent';  class LoginComponent extends React.Component {   constructor(props) {     super(props);      this.state = {       header: "Login",       id: "login-form",       name: "login-form",       items: [         {           element: "input",           type: "email",           id: "lf-email",           name: "lf-email",           value: "",           onChange: this.handleOnChangeEmail.bind(this),           placeholder: "Email",           img: {},         },         {           element: "input",           type: "password",           id: "lf-password",           name: "lf-password",           value: "",           onChange: ,           placeholder: "Password",           img: {},         },         {           element: "checkbox",           id: "lf-remember-me",           name: "lf-remember-me",           value: "lf-remember-me",           onChange: ,           display: "Remember Me",           isSelected: false         }       ]     }   }    // Figure out how to pass onChange functions per item in state.   handleOnChangeEmail(e) {      console.log("Email changed");   }    render() {     return (       <div className="LoginComponent">         {/*              Create onSubmit function for submitting the form             Create handle change functions for inputs         */}         <FormComponent id={ this.state.id } name={ this.state.name } onSubmit="" header={ this.state.header } items={ this.state.items } />       </div>     );   } }  export default LoginComponent; 

As you can see I want to pass in the handle function in the state of the component so I can uniquely handle form inputs. When I run this code though it fails because I cannot pass a function in the state. Is this type of request allowed or able to accomplish in another way?

I know you can pass the bound function to the component directly but the form component is dynamically built based on the state.item array.

Here is my form component

import React from "react"; import './FormComponent.css';  import InputComponent from './InputComponent/InputComponent'; import FormHeaderComponent from './FormHeaderComponent/FormHeaderComponent'; import CheckboxComponent from "./CheckboxComponent/CheckboxComponent";  class FormComponent extends React.Component {   render() {     const formItems = this.props.items.map((item) => {       switch(item.element) {         case "input":           return <InputComponent type={ item.type } id={ item.id } name={ item.name } placeholder={ item.placeholder } value={ item.value } onChange={ item.onChange } />         case "checkbox":           return <CheckboxComponent id={ item.id } name={ item.name } value={ item.value } selected={ item.isSelected } onChange={ item.onChange } display={ item.display } />         default:           return <InputComponent />;       }     });      return (         <form id={ this.props.id } name={ this.props.name }>             <FormHeaderComponent header={ this.props.header } />              {/*                Setup handling of submit functions               Setup handling of onchange function for inputs             */}              { formItems }         </form>     );   } }  export default FormComponent; 

As you can see in the formItems I am trying to create the elements with the onChange function from the state passed in. Any help or suggestions would be appreciated. I am well aware also I can just make the form component a component that loads all children passed so you basically build the form in the login component without state but I would prefer that not be the case.

Add certain events from one Google Calendar to another

I as well as multiple other staff in my company have regular meetings. Is it possible to make a Google Calendar which gets automatically populated when one of us schedule a meeting for a particular date? In short, if I enter the key word “meeting” on a particular date on my calendar, can a second Google Calendar be populated with the same information on that particular date?

AWS Glue ETL Job triggered on batches of S3 Events

I have an S3 bucket that gets many files dropped in it (1000 records/min). I want to trigger a Glue ETL job on batches of these dropped files.

I have looked at using Firehose to aggregate the batches of the events, but that requires a lot of chained resources. Like S3 -> Lambda -> Firehose -> …

What is the best way to process my data in batches?

Best practices for TDD on class that listens for events

I’m a TDD (test driven development) noob and am going to force myself to use it on an upcoming project. However, I foresee that my project needs an event system.

I read that you should only test public methods, but the main point of events is that there are less public methods.

I suspect I should test that a class properly receives an event when it is raised. But how? And what else should be tested? What are other things to consider?

Are there best practices for TDD with classes that listen for events? What about raising events?

Although this question applies to any OO language, I am coding in C#.

Find the expectation of the time difference between two consecutive events when the total number of events is given.

Suppose we have a Poisson process with $ \lambda$ , I am trying to find the expectation of the time difference $ \Delta_t$ , i.e., $ \mathbb{E}(\Delta_t)$ , between two consecutive events when the total number of events (denoted by $ M$ ) that happened during $ [0,1]$ is given. I know that when the $ M$ is unknown, then we know that $ \mathbb{E}(\Delta_t) = \frac{1}{\lambda}$ , is the result consistent when extra information $ M$ is given? Furthermore, if $ \lambda$ is not given but $ M$ , then what is the value of $ \mathbb{E}(\Delta_t)$ . Thanks in advance.