mirror of
https://github.com/twiglet/cs2j.git
synced 2025-01-18 13:15:17 +01:00
before invoking delegates in a Multi instance make a copy of the invocation list and invoke from that in case they manipulate the original delegate
This commit is contained in:
parent
1b2222254a
commit
d928e3c7bf
@ -21,6 +21,7 @@
|
||||
package CS2JNet.System;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import CS2JNet.JavaSupport.util.ListSupport;
|
||||
@ -32,7 +33,12 @@ import CS2JNet.JavaSupport.util.ListSupport;
|
||||
public class __MultiEventHandler<TEventArgs> implements EventHandler<TEventArgs> {
|
||||
|
||||
public void Invoke(Object other, TEventArgs e) throws Exception {
|
||||
for (EventHandler<TEventArgs> d : this.GetInvocationList())
|
||||
List<EventHandler<TEventArgs>> copy, members = this.GetInvocationList();
|
||||
synchronized (members)
|
||||
{
|
||||
copy = new LinkedList<EventHandler<TEventArgs>>(members);
|
||||
}
|
||||
for (EventHandler<TEventArgs> d : copy)
|
||||
{
|
||||
d.Invoke(other, e);
|
||||
}
|
||||
|
@ -250,6 +250,14 @@ lock(<exp>)
|
||||
<block(statements = block, indent = indent)>
|
||||
>>
|
||||
|
||||
synchstat(comments,exp,stats) ::= <<
|
||||
<comments; separator=""\n"">
|
||||
synchronized (<exp>)
|
||||
{
|
||||
<stats>
|
||||
}
|
||||
>>
|
||||
|
||||
yield(comments,exp) ::= <<
|
||||
<comments; separator=""\n"">
|
||||
yield <if(exp)>return <exp><else>break<endif>;
|
||||
|
@ -1556,8 +1556,10 @@ scope TypeContext;
|
||||
multiDelName = "__Multi" + delName;
|
||||
delClassMemberNodes = this.parseString("class_member_declarations", Fragments.MultiDelegateMethods(mkTypeString(delName, $variant_generic_parameter_list.tyargs), mkTypeString(multiDelName, $variant_generic_parameter_list.tyargs),mkTypeArgString($variant_generic_parameter_list.tyargs)));
|
||||
AddToImports("java.util.List");
|
||||
AddToImports("java.util.LinkedList");
|
||||
AddToImports("java.util.ArrayList");
|
||||
AddToImports("CS2JNet.JavaSupport.util.ListSupport");
|
||||
$NSContext::namespaces.Add("System.Collection"); // System.Collection.Ilist used in multi invoke method
|
||||
}
|
||||
magicMultiDelClass[$d.token, $atts, toplevel ? dupTree($mods) : addModifier($mods, (CommonTree)adaptor.Create(STATIC, $d.token, "static")), multiDelName, ifTree, $type_parameter_constraints_clauses.tree, $variant_generic_parameter_list.tree, $magicMultiInvokerMethod.tree, delClassMemberNodes]
|
||||
{
|
||||
@ -2259,14 +2261,28 @@ magicDelegateInterface[IToken tok, CommonTree return_type, CommonTree identifier
|
||||
;
|
||||
|
||||
// First execute all but the last one, then execute the last one and (if non-void) return its result.
|
||||
// List<CompleteCallback> copy, members = this.GetInvocationList();
|
||||
// synchronized (members) {
|
||||
// copy = new LinkedList<CompleteCallback>(members);
|
||||
// }
|
||||
// for (CompleteCallback d : copy)
|
||||
// {
|
||||
// d.Invoke(name, result);
|
||||
// }
|
||||
//
|
||||
magicMultiInvokerMethod[IToken tok, CommonTree return_type, bool retIsVoid, CommonTree type, CommonTree formal_parameter_list, CommonTree argument_list, List<String> tyArgs]
|
||||
:
|
||||
e1=magicThrowsException[Cfg.TranslatorBlanketThrow, tok]
|
||||
-> {retIsVoid}?
|
||||
^(METHOD[tok, "METHOD"] PUBLIC[tok, "public"] { dupTree($return_type) } IDENTIFIER[tok,"Invoke"] { dupTree($formal_parameter_list) }
|
||||
OPEN_BRACE[tok, "{"]
|
||||
^(TYPE[tok, "TYPE"] IDENTIFIER[tok, "IList"] LTHAN[tok, "<"] { dupTree($type) } GT[tok, ">"]) IDENTIFIER[tok, "copy"] COMMA[tok, ","] IDENTIFIER[tok, "members"] ASSIGN[tok, "="] ^(APPLY[tok, "APPLY"] ^(DOT[tok,"."] THIS[tok,"this"] IDENTIFIER[tok,"GetInvocationList"])) SEMI[tok, ";"]
|
||||
^(SYNCHRONIZED[tok, "synchronized"] IDENTIFIER[tok, "members"] OPEN_BRACE[tok, "{"]
|
||||
IDENTIFIER[tok, "copy"] ASSIGN[tok, "="] ^(NEW[tok, "new"] ^(TYPE[tok, "TYPE"] IDENTIFIER[tok, "LinkedList"] LTHAN[tok, "<"] { dupTree($type) } GT[tok, ">"]) ^(ARGS[tok, "ARGS"] IDENTIFIER[tok, "members"])) SEMI[tok, ";"]
|
||||
CLOSE_BRACE[tok, "}"]
|
||||
)
|
||||
^(FOREACH[tok, "foreach"]
|
||||
{ $type } IDENTIFIER[tok, "d"] ^(APPLY[tok, "APPLY"] ^(DOT[tok,"."] THIS[tok,"this"] IDENTIFIER[tok,"GetInvocationList"]))
|
||||
{ $type } IDENTIFIER[tok, "d"] IDENTIFIER[tok, "copy"]
|
||||
SEP[tok, "SEP"]
|
||||
OPEN_BRACE[tok, "{"]
|
||||
^(APPLY[tok, "APPLY"] ^(DOT[tok,"."] IDENTIFIER[tok,"d"] IDENTIFIER[tok,"Invoke"]) { $argument_list }) SEMI[tok, ";"]
|
||||
@ -2277,9 +2293,14 @@ magicMultiInvokerMethod[IToken tok, CommonTree return_type, bool retIsVoid, Comm
|
||||
)
|
||||
-> ^(METHOD[tok, "METHOD"] PUBLIC[tok, "public"] { dupTree($return_type) } IDENTIFIER[tok,"Invoke"] { dupTree($formal_parameter_list) }
|
||||
OPEN_BRACE[tok, "{"]
|
||||
^(TYPE[tok, "TYPE"] IDENTIFIER[tok, "IList"] LTHAN[tok, "<"] { dupTree($type) } GT[tok, ">"]) IDENTIFIER[tok, "copy"] COMMA[tok, ","] IDENTIFIER[tok, "members"] ASSIGN[tok, "="] ^(APPLY[tok, "APPLY"] ^(DOT[tok,"."] THIS[tok,"this"] IDENTIFIER[tok,"GetInvocationList"])) SEMI[tok, ";"]
|
||||
^(SYNCHRONIZED[tok, "synchronized"] IDENTIFIER[tok, "members"] OPEN_BRACE[tok, "{"]
|
||||
IDENTIFIER[tok, "copy"] ASSIGN[tok, "="] ^(NEW[tok, "new"] ^(TYPE[tok, "TYPE"] IDENTIFIER[tok, "LinkedList"] LTHAN[tok, "<"] { dupTree($type) } GT[tok, ">"]) ^(ARGS[tok, "ARGS"] IDENTIFIER[tok, "members"])) SEMI[tok, ";"]
|
||||
CLOSE_BRACE[tok, "}"]
|
||||
)
|
||||
{ $type } IDENTIFIER[tok, "prev"] ASSIGN[tok, "="] NULL[tok, "null"] SEMI[tok,";"]
|
||||
^(FOREACH[tok, "foreach"]
|
||||
{ $type } IDENTIFIER[tok, "d"] ^(APPLY[tok, "APPLY"] ^(DOT[tok,"."] THIS[tok,"this"] IDENTIFIER[tok,"GetInvocationList"]))
|
||||
{ $type } IDENTIFIER[tok, "d"] IDENTIFIER[tok, "copy"]
|
||||
SEP[tok, "SEP"]
|
||||
OPEN_BRACE[tok, "{"]
|
||||
^(IF[tok, "if"] ^(NOT_EQUAL[tok, "!="] IDENTIFIER[tok,"prev"] NULL[tok, "null"]) SEP ^(APPLY[tok, "APPLY"] ^(DOT[tok,"."] IDENTIFIER[tok,"prev"] IDENTIFIER[tok,"Invoke"]) { $argument_list }) SEMI[tok, ";"])
|
||||
|
@ -1465,6 +1465,7 @@ embedded_statement returns [bool isSemi, bool isIf, bool indent]
|
||||
catches = { $catch_clauses.st }, fin = { $finally_clause.st } )
|
||||
| checked_statement -> { $checked_statement.st }
|
||||
| unchecked_statement -> { $unchecked_statement.st }
|
||||
| synchronized_statement -> { $synchronized_statement.st }
|
||||
| lock_statement -> { $lock_statement.st }
|
||||
| yield_statement -> { $yield_statement.st }
|
||||
| ^('unsafe' { preComments = CollectedComments; } block { someText = %op(); %{someText}.op="unsafe"; %{someText}.post = $block.st; })
|
||||
@ -1564,6 +1565,10 @@ catch_clause:
|
||||
^('catch' type identifier block) -> catch_template(type = { $type.st }, id = { $identifier.st }, block = {$block.st}, blockindent = { $block.isSemi } );
|
||||
finally_clause:
|
||||
^('finally' block) -> fin(block = {$block.st}, blockindent = { $block.isSemi });
|
||||
|
||||
synchronized_statement:
|
||||
^(SYNCHRONIZED expression '{' s+=statement* '}') -> synchstat(exp={ $expression.st }, stats = { $s });
|
||||
|
||||
checked_statement
|
||||
@init {
|
||||
StringTemplate someText = null;
|
||||
|
@ -519,7 +519,7 @@ scope MkNonGeneric {
|
||||
}
|
||||
|
||||
protected CommonTree mkJavaRep(IToken tok, TypeRepTemplate ty) {
|
||||
if (ty.InstantiatedTypes.Length == 0) {
|
||||
if (ty.InstantiatedTypes == null || ty.InstantiatedTypes.Length == 0) {
|
||||
return (CommonTree)adaptor.Create(IDENTIFIER, tok, ty.Java);
|
||||
}
|
||||
else {
|
||||
@ -2634,6 +2634,7 @@ embedded_statement[bool isStatementListCtxt]
|
||||
| ^('try' block catch_clauses? finally_clause?)
|
||||
| checked_statement
|
||||
| unchecked_statement
|
||||
| synchronized_statement // Java: synchronized(obj) {}
|
||||
| lock_statement
|
||||
| yield_statement
|
||||
| ^('unsafe' block)
|
||||
@ -2932,6 +2933,10 @@ checked_statement:
|
||||
'checked' block ;
|
||||
unchecked_statement:
|
||||
^(UNCHECKED block) ;
|
||||
|
||||
synchronized_statement:
|
||||
^(SYNCHRONIZED expression[ObjectType] '{' statement_list '}') ;
|
||||
|
||||
lock_statement:
|
||||
'lock' '(' expression[ObjectType] ')' embedded_statement[/* isStatementListCtxt */ false] ;
|
||||
|
||||
|
@ -148,6 +148,8 @@ tokens {
|
||||
|
||||
EXCEPTION;
|
||||
|
||||
SYNCHRONIZED;
|
||||
|
||||
PAYLOAD; // carries arbitrary text for the output file
|
||||
PAYLOAD_LIST;
|
||||
JAVAWRAPPER;
|
||||
|
Loading…
x
Reference in New Issue
Block a user