1// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5'use strict';
6
7base.require('base.settings');
8
9base.exportTo('tracing', function() {
10  var Settings = base.Settings;
11
12  /**
13   * A way to persist settings specific to parts of a trace model.
14   *
15   * This object should not be persisted because it builds up internal data
16   * structures that map model objects to settings keys. It should thus be
17   * created for the druation of whatever interaction(s) you're going to do with
18   * model settings, and then discarded.
19   *
20   * This system works on a notion of an object key: for an object's key, it
21   * considers all the other keys in the model. If it is unique, then the key is
22   * persisted to base.Settings. However, if it is not unique, then the
23   * setting is stored on the object itself. Thus, objects with unique keys will
24   * be persisted across page reloads, whereas objects with nonunique keys will
25   * not.
26   */
27  function TraceModelSettings(model) {
28    this.model = model;
29    this.objectsByKey_ = [];
30    this.nonuniqueKeys_ = [];
31    this.buildObjectsByKeyMap_();
32    this.removeNonuniqueKeysFromSettings_();
33  }
34
35  TraceModelSettings.prototype = {
36    buildObjectsByKeyMap_: function() {
37      var objects = [this.model.kernel];
38      objects.push.apply(objects,
39                         base.dictionaryValues(this.model.processes));
40      objects.push.apply(objects,
41                         this.model.getAllThreads());
42      var objectsByKey = {};
43      var NONUNIQUE_KEY = 'nonuniqueKey';
44      for (var i = 0; i < objects.length; i++) {
45        var object = objects[i];
46        var objectKey = object.getSettingsKey();
47        if (!objectKey)
48          continue;
49        if (objectsByKey[objectKey] === undefined) {
50          objectsByKey[objectKey] = object;
51          continue;
52        }
53        objectsByKey[objectKey] = NONUNIQUE_KEY;
54      }
55
56      var nonuniqueKeys = {};
57      base.dictionaryKeys(objectsByKey).forEach(function(objectKey) {
58        if (objectsByKey[objectKey] !== NONUNIQUE_KEY)
59          return;
60        delete objectsByKey[objectKey];
61        nonuniqueKeys[objectKey] = true;
62      });
63
64      this.nonuniqueKeys = nonuniqueKeys;
65      this.objectsByKey_ = objectsByKey;
66    },
67
68    removeNonuniqueKeysFromSettings_: function() {
69      var settings = Settings.get('trace_model_settings', {});
70      var settingsChanged = false;
71      base.dictionaryKeys(settings).forEach(function(objectKey) {
72        if (!this.nonuniqueKeys[objectKey])
73          return;
74        settingsChanged = true;
75        delete settings[objectKey];
76      }, this);
77      if (settingsChanged)
78        Settings.set('trace_model_settings', settings);
79    },
80
81    hasUniqueSettingKey: function(object) {
82      var objectKey = object.getSettingsKey();
83      if (!objectKey)
84        return false;
85      return this.objectsByKey_[objectKey] !== undefined;
86    },
87
88    getSettingFor: function(object, objectLevelKey, defaultValue) {
89      var objectKey = object.getSettingsKey();
90      if (!objectKey || !this.objectsByKey_[objectKey]) {
91        var ephemeralValue = object.ephemeralSettings[objectLevelKey];
92        if (ephemeralValue !== undefined)
93          return ephemeralValue;
94        return defaultValue;
95      }
96
97      var settings = Settings.get('trace_model_settings', {});
98      if (!settings[objectKey])
99        settings[objectKey] = {};
100      var value = settings[objectKey][objectLevelKey];
101      if (value !== undefined)
102        return value;
103      return defaultValue;
104    },
105
106    setSettingFor: function(object, objectLevelKey, value) {
107      var objectKey = object.getSettingsKey();
108      if (!objectKey || !this.objectsByKey_[objectKey]) {
109        object.ephemeralSettings[objectLevelKey] = value;
110        return;
111      }
112
113      var settings = Settings.get('trace_model_settings', {});
114      if (!settings[objectKey])
115        settings[objectKey] = {};
116      settings[objectKey][objectLevelKey] = value;
117      Settings.set('trace_model_settings', settings);
118    }
119  };
120
121  return {
122    TraceModelSettings: TraceModelSettings
123  };
124});
125