Subversion Repository Public Repository

litesoft

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
/*
 * Copyright 2008 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package com.google.gwt.gen2.event.shared;

import com.google.gwt.core.client.*;
import com.google.gwt.gen2.event.shared.AbstractEvent.*;

/**
 * Default JavaScript handler registry. This is in the shared package so we
 * don't have to make it public, should never be called outside of a GWT runtime
 * environment.
 * <p/>
 * Th JsHandlerRegistry makes use of the fact that in the large majority of
 * cases, only one or two handlers are added for each event type. Therefore,
 * rather than storing handlers in a list of lists, we store then in a single
 * flattened array with an escape clause to handle the rare case where we have
 * more handlers then expected.
 */
class JsHandlerRegistry extends JavaScriptObject {

    public static JsHandlerRegistry create() {
        return (JsHandlerRegistry) JavaScriptObject.createObject();
    }

    /**
     * Required constructor.
     */
    protected JsHandlerRegistry() {
    }

    public final void addHandler( AbstractEvent.Type eventKey, EventHandler handler ) {
        // The base is the equivalent to a c pointer into the flattened handler data
        // structure.
        int base = eventKey.hashCode();
        int count = getCount( base );

        // If we already have the maximum number of handlers we can store in the
        // flattened data structure, store the handlers in an external list instead.
        if ( count == HandlerManager.EXPECTED_HANDLERS && isFlattened( base ) ) {
            unflatten( base );
        }
        setHandler( base, count, handler, isFlattened( base ) );
        setCount( base, count + 1 );
    }

    public final void clearHandlers( Type<?, ?> type ) {
        int base = type.hashCode();
        // Clearing handlers is relatively unusual, so the cost of unflattening the
        // handler list is justified by the smaller code.
        unflatten( base );

        // Replace the list of handlers.
        setHandlerList( base + 1, JavaScriptObject.createArray() );
        setCount( base, 0 );
    }

    public final void fireEvent( AbstractEvent event ) {
        Type type = event.getType();
        int base = type.hashCode();
        int count = getCount( base );
        boolean isFlattened = isFlattened( base );

        for ( int i = 0; i < count; i++ ) {
            // Gets the given handler to fire.
            EventHandler handler = getHandler( base, i, isFlattened );

            // Fires the handler.
            type.fire( handler, event );
        }
    }

    public final EventHandler getHandler( AbstractEvent.Type eventKey, int index ) {
        int base = eventKey.hashCode();
        int count = getCount( base );
        if ( index >= count ) {
            throw new IndexOutOfBoundsException( "index: " + index );
        }
        return getHandler( base, index, isFlattened( base ) );
    }

    public final int getHandlerCount( AbstractEvent.Type eventKey ) {
        return getCount( eventKey.hashCode() );
    }

    public final void removeHandler( AbstractEvent.Type eventKey, EventHandler handler ) {
        int base = eventKey.hashCode();

        // Removing a handler is unusual, so smaller code is preferable then
        // handling both flat and dangling list of pointers.
        if ( isFlattened( base ) ) {
            unflatten( base );
        }
        boolean result = removeHelper( base, handler );
        // Hiding this behind an assertion as we'd rather not force the compiler to
        // have to include all handler.toString() instances.
        assert result : handler + " did not exist";
    }

    private native int getCount( int index ) /*-{
        var count = this[index];
        return count == null ? 0 : count;
    }-*/;

    private native EventHandler getHandler( int base, int index, boolean flattened ) /*-{
        return flattened ? this[base + 2 + index] : this[base + 1][index];
    }-*/;

    private native boolean isFlattened( int base ) /*-{
        return this[base + 1] == null;
    }-*/;

    private native boolean removeHelper( int base, EventHandler handler ) /*-{
        // Find the handler.
        var count = this[base];
        var handlerList = this[base + 1];
        var handlerIndex = -1;
        for ( var index = 0; index < count; index++ )
        {
            if ( handlerList[index] == handler )
            {
                handlerIndex = index;
                break;
            }
        }
        if ( handlerIndex == -1 )
        {
            return false;
        }

        // Remove the handler.
        var last = count - 1;
        for ( ; handlerIndex < last; handlerIndex++ )
        {
            handlerList[handlerIndex] = handlerList[handlerIndex + 1]
        }
        handlerList[last] = null;
        this[base] = this[base] - 1;
        return true;
    }-*/;

    private native void setCount( int index, int count ) /*-{
        this[index] = count;
    }-*/;

    private native void setHandler( int base, int index, EventHandler handler, boolean flattened ) /*-{
        if ( flattened )
        {
            this[base + 2 + index] = handler;
        }
        else
        {
            this[base + 1][index] = handler;
        }
    }-*/;

    private native void setHandlerList( int base, JavaScriptObject handlerList ) /*-{
        this[base + 1] = handlerList;
    }-*/;

    private native void unflatten( int base ) /*-{
        var handlerList = {};
        var count = this[base];
        var start = base + 2;
        for ( var i = 0; i < count; i++ )
        {
            handlerList[i] = this[start + i];
            this[start + i] = null;
        }
        this[base + 1] = handlerList;
    }-*/;
}

Commits for litesoft/trunk/Java/GWT/Client/src/com/google/gwt/gen2/event/shared/JsHandlerRegistry.java

Diff revisions: vs.
Revision Author Commited Message
950 Diff Diff GeorgeS picture GeorgeS Thu 19 Jun, 2014 17:57:04 +0000

New Lines

948 Diff Diff GeorgeS picture GeorgeS Sat 07 Jun, 2014 23:42:39 +0000

Jusefuls Formatter Updated to New Code Format

475 Diff Diff GeorgeS picture GeorgeS Sat 03 Sep, 2011 13:54:51 +0000
282 GeorgeS picture GeorgeS Fri 17 Jun, 2011 13:54:39 +0000