From 6ad59ca0d2bd231ebd709b510167e75ec74efcc6 Mon Sep 17 00:00:00 2001
From: David Sehnal <david.sehnal@gmail.com>
Date: Sat, 24 Nov 2018 23:29:34 +0100
Subject: [PATCH] mol-state: do not show time for null objects; better
 multi-select params comparison

---
 src/mol-state/state.ts           |  6 +++---
 src/mol-util/param-definition.ts | 17 +++++++++++++++++
 2 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/src/mol-state/state.ts b/src/mol-state/state.ts
index 5c74ca8ca..e9ed797ff 100644
--- a/src/mol-state/state.ts
+++ b/src/mol-state/state.ts
@@ -474,13 +474,13 @@ async function updateSubtree(ctx: UpdateContext, root: Ref) {
         ctx.results.push(update);
         if (update.action === 'created') {
             isNull = update.obj === StateObject.Null;
-            ctx.parent.events.log.next(LogEntry.info(`Created ${update.obj.label} in ${formatTimespan(time)}.`));
+            if (!isNull) ctx.parent.events.log.next(LogEntry.info(`Created ${update.obj.label} in ${formatTimespan(time)}.`));
         } else if (update.action === 'updated') {
             isNull = update.obj === StateObject.Null;
-            ctx.parent.events.log.next(LogEntry.info(`Updated ${update.obj.label} in ${formatTimespan(time)}.`));
+            if (!isNull) ctx.parent.events.log.next(LogEntry.info(`Updated ${update.obj.label} in ${formatTimespan(time)}.`));
         } else if (update.action === 'replaced') {
             isNull = update.obj === StateObject.Null;
-            ctx.parent.events.log.next(LogEntry.info(`Updated ${update.obj.label} in ${formatTimespan(time)}.`));
+            if (!isNull) ctx.parent.events.log.next(LogEntry.info(`Updated ${update.obj.label} in ${formatTimespan(time)}.`));
         }
     } catch (e) {
         ctx.changed = true;
diff --git a/src/mol-util/param-definition.ts b/src/mol-util/param-definition.ts
index 5bdde061f..f6cd42763 100644
--- a/src/mol-util/param-definition.ts
+++ b/src/mol-util/param-definition.ts
@@ -231,6 +231,23 @@ export namespace ParamDefinition {
             if (u.name !== v.name) return false;
             const map = p.map(u.name);
             return isParamEqual(map, u.params, v.params);
+        } else if (p.type === 'multi-select') {
+            const u = a as MultiSelect<any>['defaultValue'], v = b as MultiSelect<any>['defaultValue'];
+            if (u.length !== v.length) return false;
+            if (u.length < 10) {
+                for (let i = 0, _i = u.length; i < _i; i++) {
+                    if (u[i] === v[i]) continue;
+                    if (v.indexOf(u[i]) < 0) return false;
+                }
+            } else {
+                // TODO: should the value of multiselect be a set?
+                const vSet = new Set(v);
+                for (let i = 0, _i = u.length; i < _i; i++) {
+                    if (u[i] === v[i]) continue;
+                    if (!vSet.has(u[i])) return false;
+                }
+            }
+            return true;
         } else if (p.type === 'interval') {
             return a[0] === b[0] && a[1] === b[1];
         } else if (p.type === 'line-graph') {
-- 
GitLab