Subversion Repository Public Repository

litesoft

Diff Revisions 949 vs 950 for /trunk/Java/GWT/Client/src/com/google/gwt/gen2/event/shared/JsHandlerRegistry.java

Diff revisions: vs.
  @@ -1,185 +1,185 @@
1 - /*
2 - * Copyright 2008 Google Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 - * use this file except in compliance with the License. You may obtain a copy of
6 - * the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 - * License for the specific language governing permissions and limitations under
14 - * the License.
15 - */
16 -
17 - package com.google.gwt.gen2.event.shared;
18 -
19 - import com.google.gwt.core.client.*;
20 - import com.google.gwt.gen2.event.shared.AbstractEvent.*;
21 -
22 - /**
23 - * Default JavaScript handler registry. This is in the shared package so we
24 - * don't have to make it public, should never be called outside of a GWT runtime
25 - * environment.
26 - * <p/>
27 - * Th JsHandlerRegistry makes use of the fact that in the large majority of
28 - * cases, only one or two handlers are added for each event type. Therefore,
29 - * rather than storing handlers in a list of lists, we store then in a single
30 - * flattened array with an escape clause to handle the rare case where we have
31 - * more handlers then expected.
32 - */
33 - class JsHandlerRegistry extends JavaScriptObject {
34 -
35 - public static JsHandlerRegistry create() {
36 - return (JsHandlerRegistry) JavaScriptObject.createObject();
37 - }
38 -
39 - /**
40 - * Required constructor.
41 - */
42 - protected JsHandlerRegistry() {
43 - }
44 -
45 - public final void addHandler( AbstractEvent.Type eventKey, EventHandler handler ) {
46 - // The base is the equivalent to a c pointer into the flattened handler data
47 - // structure.
48 - int base = eventKey.hashCode();
49 - int count = getCount( base );
50 -
51 - // If we already have the maximum number of handlers we can store in the
52 - // flattened data structure, store the handlers in an external list instead.
53 - if ( count == HandlerManager.EXPECTED_HANDLERS && isFlattened( base ) ) {
54 - unflatten( base );
55 - }
56 - setHandler( base, count, handler, isFlattened( base ) );
57 - setCount( base, count + 1 );
58 - }
59 -
60 - public final void clearHandlers( Type<?, ?> type ) {
61 - int base = type.hashCode();
62 - // Clearing handlers is relatively unusual, so the cost of unflattening the
63 - // handler list is justified by the smaller code.
64 - unflatten( base );
65 -
66 - // Replace the list of handlers.
67 - setHandlerList( base + 1, JavaScriptObject.createArray() );
68 - setCount( base, 0 );
69 - }
70 -
71 - public final void fireEvent( AbstractEvent event ) {
72 - Type type = event.getType();
73 - int base = type.hashCode();
74 - int count = getCount( base );
75 - boolean isFlattened = isFlattened( base );
76 -
77 - for ( int i = 0; i < count; i++ ) {
78 - // Gets the given handler to fire.
79 - EventHandler handler = getHandler( base, i, isFlattened );
80 -
81 - // Fires the handler.
82 - type.fire( handler, event );
83 - }
84 - }
85 -
86 - public final EventHandler getHandler( AbstractEvent.Type eventKey, int index ) {
87 - int base = eventKey.hashCode();
88 - int count = getCount( base );
89 - if ( index >= count ) {
90 - throw new IndexOutOfBoundsException( "index: " + index );
91 - }
92 - return getHandler( base, index, isFlattened( base ) );
93 - }
94 -
95 - public final int getHandlerCount( AbstractEvent.Type eventKey ) {
96 - return getCount( eventKey.hashCode() );
97 - }
98 -
99 - public final void removeHandler( AbstractEvent.Type eventKey, EventHandler handler ) {
100 - int base = eventKey.hashCode();
101 -
102 - // Removing a handler is unusual, so smaller code is preferable then
103 - // handling both flat and dangling list of pointers.
104 - if ( isFlattened( base ) ) {
105 - unflatten( base );
106 - }
107 - boolean result = removeHelper( base, handler );
108 - // Hiding this behind an assertion as we'd rather not force the compiler to
109 - // have to include all handler.toString() instances.
110 - assert result : handler + " did not exist";
111 - }
112 -
113 - private native int getCount( int index ) /*-{
114 - var count = this[index];
115 - return count == null ? 0 : count;
116 - }-*/;
117 -
118 - private native EventHandler getHandler( int base, int index, boolean flattened ) /*-{
119 - return flattened ? this[base + 2 + index] : this[base + 1][index];
120 - }-*/;
121 -
122 - private native boolean isFlattened( int base ) /*-{
123 - return this[base + 1] == null;
124 - }-*/;
125 -
126 - private native boolean removeHelper( int base, EventHandler handler ) /*-{
127 - // Find the handler.
128 - var count = this[base];
129 - var handlerList = this[base + 1];
130 - var handlerIndex = -1;
131 - for ( var index = 0; index < count; index++ )
132 - {
133 - if ( handlerList[index] == handler )
134 - {
135 - handlerIndex = index;
136 - break;
137 - }
138 - }
139 - if ( handlerIndex == -1 )
140 - {
141 - return false;
142 - }
143 -
144 - // Remove the handler.
145 - var last = count - 1;
146 - for ( ; handlerIndex < last; handlerIndex++ )
147 - {
148 - handlerList[handlerIndex] = handlerList[handlerIndex + 1]
149 - }
150 - handlerList[last] = null;
151 - this[base] = this[base] - 1;
152 - return true;
153 - }-*/;
154 -
155 - private native void setCount( int index, int count ) /*-{
156 - this[index] = count;
157 - }-*/;
158 -
159 - private native void setHandler( int base, int index, EventHandler handler, boolean flattened ) /*-{
160 - if ( flattened )
161 - {
162 - this[base + 2 + index] = handler;
163 - }
164 - else
165 - {
166 - this[base + 1][index] = handler;
167 - }
168 - }-*/;
169 -
170 - private native void setHandlerList( int base, JavaScriptObject handlerList ) /*-{
171 - this[base + 1] = handlerList;
172 - }-*/;
173 -
174 - private native void unflatten( int base ) /*-{
175 - var handlerList = {};
176 - var count = this[base];
177 - var start = base + 2;
178 - for ( var i = 0; i < count; i++ )
179 - {
180 - handlerList[i] = this[start + i];
181 - this[start + i] = null;
182 - }
183 - this[base + 1] = handlerList;
184 - }-*/;
185 - }
1 + /*
2 + * Copyright 2008 Google Inc.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 + * use this file except in compliance with the License. You may obtain a copy of
6 + * the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 + * License for the specific language governing permissions and limitations under
14 + * the License.
15 + */
16 +
17 + package com.google.gwt.gen2.event.shared;
18 +
19 + import com.google.gwt.core.client.*;
20 + import com.google.gwt.gen2.event.shared.AbstractEvent.*;
21 +
22 + /**
23 + * Default JavaScript handler registry. This is in the shared package so we
24 + * don't have to make it public, should never be called outside of a GWT runtime
25 + * environment.
26 + * <p/>
27 + * Th JsHandlerRegistry makes use of the fact that in the large majority of
28 + * cases, only one or two handlers are added for each event type. Therefore,
29 + * rather than storing handlers in a list of lists, we store then in a single
30 + * flattened array with an escape clause to handle the rare case where we have
31 + * more handlers then expected.
32 + */
33 + class JsHandlerRegistry extends JavaScriptObject {
34 +
35 + public static JsHandlerRegistry create() {
36 + return (JsHandlerRegistry) JavaScriptObject.createObject();
37 + }
38 +
39 + /**
40 + * Required constructor.
41 + */
42 + protected JsHandlerRegistry() {
43 + }
44 +
45 + public final void addHandler( AbstractEvent.Type eventKey, EventHandler handler ) {
46 + // The base is the equivalent to a c pointer into the flattened handler data
47 + // structure.
48 + int base = eventKey.hashCode();
49 + int count = getCount( base );
50 +
51 + // If we already have the maximum number of handlers we can store in the
52 + // flattened data structure, store the handlers in an external list instead.
53 + if ( count == HandlerManager.EXPECTED_HANDLERS && isFlattened( base ) ) {
54 + unflatten( base );
55 + }
56 + setHandler( base, count, handler, isFlattened( base ) );
57 + setCount( base, count + 1 );
58 + }
59 +
60 + public final void clearHandlers( Type<?, ?> type ) {
61 + int base = type.hashCode();
62 + // Clearing handlers is relatively unusual, so the cost of unflattening the
63 + // handler list is justified by the smaller code.
64 + unflatten( base );
65 +
66 + // Replace the list of handlers.
67 + setHandlerList( base + 1, JavaScriptObject.createArray() );
68 + setCount( base, 0 );
69 + }
70 +
71 + public final void fireEvent( AbstractEvent event ) {
72 + Type type = event.getType();
73 + int base = type.hashCode();
74 + int count = getCount( base );
75 + boolean isFlattened = isFlattened( base );
76 +
77 + for ( int i = 0; i < count; i++ ) {
78 + // Gets the given handler to fire.
79 + EventHandler handler = getHandler( base, i, isFlattened );
80 +
81 + // Fires the handler.
82 + type.fire( handler, event );
83 + }
84 + }
85 +
86 + public final EventHandler getHandler( AbstractEvent.Type eventKey, int index ) {
87 + int base = eventKey.hashCode();
88 + int count = getCount( base );
89 + if ( index >= count ) {
90 + throw new IndexOutOfBoundsException( "index: " + index );
91 + }
92 + return getHandler( base, index, isFlattened( base ) );
93 + }
94 +
95 + public final int getHandlerCount( AbstractEvent.Type eventKey ) {
96 + return getCount( eventKey.hashCode() );
97 + }
98 +
99 + public final void removeHandler( AbstractEvent.Type eventKey, EventHandler handler ) {
100 + int base = eventKey.hashCode();
101 +
102 + // Removing a handler is unusual, so smaller code is preferable then
103 + // handling both flat and dangling list of pointers.
104 + if ( isFlattened( base ) ) {
105 + unflatten( base );
106 + }
107 + boolean result = removeHelper( base, handler );
108 + // Hiding this behind an assertion as we'd rather not force the compiler to
109 + // have to include all handler.toString() instances.
110 + assert result : handler + " did not exist";
111 + }
112 +
113 + private native int getCount( int index ) /*-{
114 + var count = this[index];
115 + return count == null ? 0 : count;
116 + }-*/;
117 +
118 + private native EventHandler getHandler( int base, int index, boolean flattened ) /*-{
119 + return flattened ? this[base + 2 + index] : this[base + 1][index];
120 + }-*/;
121 +
122 + private native boolean isFlattened( int base ) /*-{
123 + return this[base + 1] == null;
124 + }-*/;
125 +
126 + private native boolean removeHelper( int base, EventHandler handler ) /*-{
127 + // Find the handler.
128 + var count = this[base];
129 + var handlerList = this[base + 1];
130 + var handlerIndex = -1;
131 + for ( var index = 0; index < count; index++ )
132 + {
133 + if ( handlerList[index] == handler )
134 + {
135 + handlerIndex = index;
136 + break;
137 + }
138 + }
139 + if ( handlerIndex == -1 )
140 + {
141 + return false;
142 + }
143 +
144 + // Remove the handler.
145 + var last = count - 1;
146 + for ( ; handlerIndex < last; handlerIndex++ )
147 + {
148 + handlerList[handlerIndex] = handlerList[handlerIndex + 1]
149 + }
150 + handlerList[last] = null;
151 + this[base] = this[base] - 1;
152 + return true;
153 + }-*/;
154 +
155 + private native void setCount( int index, int count ) /*-{
156 + this[index] = count;
157 + }-*/;
158 +
159 + private native void setHandler( int base, int index, EventHandler handler, boolean flattened ) /*-{
160 + if ( flattened )
161 + {
162 + this[base + 2 + index] = handler;
163 + }
164 + else
165 + {
166 + this[base + 1][index] = handler;
167 + }
168 + }-*/;
169 +
170 + private native void setHandlerList( int base, JavaScriptObject handlerList ) /*-{
171 + this[base + 1] = handlerList;
172 + }-*/;
173 +
174 + private native void unflatten( int base ) /*-{
175 + var handlerList = {};
176 + var count = this[base];
177 + var start = base + 2;
178 + for ( var i = 0; i < count; i++ )
179 + {
180 + handlerList[i] = this[start + i];
181 + this[start + i] = null;
182 + }
183 + this[base + 1] = handlerList;
184 + }-*/;
185 + }