tag:blogger.com,1999:blog-82439610697078314852024-03-08T09:59:54.813+01:00ZambochPavel Ĺ avara coding for funZhttp://www.blogger.com/profile/02673125542713538726noreply@blogger.comBlogger63125tag:blogger.com,1999:blog-8243961069707831485.post-31983747774665305022019-04-01T14:59:00.000+02:002019-04-01T18:33:19.350+02:00Rust language - WASM - WebGL - Game Of Life demo<p>Today I would shortly describe my first journey to <a href="https://rust-lang.org">Rust language</a>.
I combined multiple examples from Rust <a href="https://github.com/rustwasm/wasm-bindgen/tree/master/examples">WASM documentation</a>, <a href="https://en.wikipedia.org/wiki/WebGL">WebGL</a>.
Whole <a href="https://github.com/pavelsavara/game-of-life">code is here </a>it was fun.
</p>
<p>The implementation of <a href="https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life">Game Of Life</a> is in functional style. The previous generation is list of cell coordinates. I learned about Rust <a href="https://docs.rs/itertools/0.8.0/itertools/">itertools</a>
<pre class="csharpcode">
const OFFSETS_AROUND: [[i32; 2]; 9] = [
[-1, -1],[0, -1],[1, -1],
[-1, 0],[0, 0],[1, 0],
[-1, 1],[0, 1],[1, 1],
];
pub fn cells_around(current: &Cell) -> BoolCells {
OFFSETS_AROUND.iter()
.map(|o| {
(
o[0] == 0 && o[1] == 0,
Cell {
x: (current.x + o[0]),
y: (current.y + o[1]),
},
)
})
.collect::<BoolCells>()
}
fn should_live<I>(group: I) -> bool where I: IntoIterator<Item = BoolCell> {
let (was_alive, count) = group.into_iter()
.fold((false, 0), |acc, candidate| match candidate.0 {
true => (true, acc.1),
false => (acc.0, acc.1 + 1),
});
count == 3 || (count == 2 && was_alive)
}
pub fn next_gen(generation: &Cells) -> Cells {
let candidates_with_duplicates = generation.iter()
.map(cells_around)
.flatten();
let grouped_by_location = candidates_with_duplicates
.sorted_by(|candidate_a, candidate_b| candidate_a.1.cmp(&candidate_b.1))
.group_by(|candidate| candidate.1.clone());
grouped_by_location.into_iter()
.map(|(key, group)| {
let alive = should_live(group.into_iter());
let cell =key.clone();
(alive, cell)
})
.filter(|c| c.0)
.map(|c| c.1)
.collect::<Cells>()
}
</pre>
</p>
<p>
I stolen most of <a href="https://github.com/pavelsavara/game-of-life/blob/master/src/web.rs">my WebGl</a> code from <a href="https://github.com/rustwasm/wasm-bindgen/tree/master/examples/webgl">this demo</a>. I learned how to move code to modules and how to work with namespaces. For each live cell I tell WebGL to render 2 triangles. There is Z axis of the vertice, which I do not use, but have to pass it. So in total I'm passing single array of float[18*live-cells] to WebGL for rendering in single call. I guess it's much faster than using canvas API with call per cell.
</p>
<p>
All is integrated into WASM library all the plumbing is again stolen from <a href="https://rustwasm.github.io/wasm-bindgen/introduction.html">wasm-bindgen documentation</a>.
</p>
<p> Here is the demo. If it doesn't render for you, check your adblock settings, maybe it's blocking all .wasm files to prevent crypto-currerncy mining.
<iframe src="https://pavelsavara.github.io/game-of-life/" height="400" width="400" frameborder="0" scrolling="no"></iframe>
</p>
Zhttp://www.blogger.com/profile/02673125542713538726noreply@blogger.com2tag:blogger.com,1999:blog-8243961069707831485.post-21565965057497650882014-09-24T01:52:00.000+02:002014-09-24T01:54:01.982+02:00jni4net 0.8.8 - release<h3>Changes</h3>
<li>[#35] - fixed - Integer overflow on 64-bit OS [by Geert Claeys]</li>
<li>reworked contributed code to become full owner of the code and be able to change license.</li>
<li>changed runtime license to MIT. Tools still GPLv3.</li>
<li>moved to <a href="https://github.com/jni4net/jni4net">github</a> and <a href="https://jni4net.github.io/">jni4net.github.io</a></li>
<li>changed documentation to MarkDown and improved a bit. Links to new issue tracker and stackoverflow.</li>
<li>removed support for publishing jni4net to maven repository on google code.</li>
Hope that community would enjoy the freedoms of MIT license and github and would fork it and contribute back :-)
</br></br>
Download <a href="http://sourceforge.net/projects/jni4net/files/0.8.8/jni4net-0.8.8.0-bin.zip/download">here</a><br/><br/>Zhttp://www.blogger.com/profile/02673125542713538726noreply@blogger.com0tag:blogger.com,1999:blog-8243961069707831485.post-25334135529941082832012-03-07T01:39:00.000+01:002012-03-07T01:44:15.953+01:00Unit of work using lambdasAre you tired of writing into log file on every begin and end of the method ? Use <a href="http://en.wikipedia.org/wiki/Aspect-oriented_programming">AOP</a>. Well, not yet ready for post-compiler magic or dynamic runtime proxies ? Let's try lambdas (again).<br />
<br />
<pre class="csharpcode"><span class="kwrd">static</span> <span class="kwrd">void</span> Main(<span class="kwrd">string</span>[] args)
{
Scope<LoggingFrame>.Wrap(() =>
{
Console.WriteLine(<span class="str">"Hello world"</span>);
});
}</pre>
<br />
Would produce this console
<br />
<pre style="background: black; color: white;">2012-03-07 00:46:58,248 DEBUG - BEGIN Main
Hello world
2012-03-07 00:46:58,258 DEBUG - END Main
</pre>
<br />
How to implement that ?
<br />
<pre class="csharpcode">[DebuggerStepThrough]
<span class="kwrd">public</span> <span class="kwrd">class</span> Scope<TAdvice> where TAdvice : IAdvice, <span class="kwrd">new</span>()
{
<span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">void</span> Wrap(Action body)
{
IAdvice advice = Activator.CreateInstance<TAdvice>();
advice.OnEntry(body);
<span class="kwrd">try</span>
{
body();
advice.OnLeave(body);
}
<span class="kwrd">catch</span> (Exception ex)
{
advice.OnException(body, ex);
<span class="kwrd">throw</span>;
}
<span class="kwrd">finally</span>
{
advice.OnFinally(body);
}
}
}</pre>
<!-- code formatted by http://manoli.net/csharpformat/ -->
<pre class="csharpcode">
<span class="kwrd">public</span> <span class="kwrd">interface</span> IAdvice
{
<span class="kwrd">void</span> OnEntry(Delegate body);
<span class="kwrd">void</span> OnLeave(Delegate body);
<span class="kwrd">void</span> OnException(Delegate body, Exception exception);
<span class="kwrd">void</span> OnFinally(Delegate body);
}
</pre>
Implementation of the LoggingFrame <a href="http://en.wikipedia.org/wiki/Advice_in_aspect-oriented_programming">advice</a> is trivial.<br />
<br />
Note that you could get similar behavior with IDisposable and using keyword, but you would not be able to log pending exception.<br />
You could also think about TransactionScope, which would call tx.Complete() automatically when no exception is thrown.<br />
Further improvement is to use dependency injection to instantiate the advises.<br />
<br />
Another use-case is to implement <a href="http://martinfowler.com/eaaCatalog/unitOfWork.html">Unit of Work</a> or session/call context, while using <a href="http://en.wikipedia.org/wiki/Thread-local_storage">TSL</a> to reach topmost frame. I used it for NHibernate Session and EF DbContext (unit of work) recently. Interesting related article <a href="http://nhforge.org/wikis/patternsandpractices/nhibernate-and-the-unit-of-work-pattern.aspx">here</a>.<br />
<br />
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> Main(<span class="kwrd">string</span>[] args)
{
Scope<UnitOfWork>.Wrap(session =>
{
<span class="kwrd">var</span> people = session.Person
.Where(person => person.FirstName == <span class="str">"Pavel"</span>)
.ToList();
NestedLogic(people);
<span class="rem">//DbContext.SaveChanges() will be called here</span>
});
}
<span class="kwrd">private</span> <span class="kwrd">void</span> NestedLogic(IList<Person> people)
{
<span class="rem">//this will lookup parent session in TSL and reuse it</span>
Scope<UnitOfWork>.Wrap(session =>
{
<span class="kwrd">foreach</span> (<span class="kwrd">var</span> person <span class="kwrd">in</span> people)
{
<span class="kwrd">if</span> (person.LastName == <span class="str">"Savara"</span>)
{
person.Coder = <span class="kwrd">true</span>;
}
<span class="kwrd">else</span>
{
session.Person.Remove(person);
}
}
});
}</pre>
<br />
Composition of scopes could be beautified.
<br />
<!-- code formatted by http://manoli.net/csharpformat/ -->
<pre class="csharpcode">
Scope<LoggingFrame, TransactionFrame>.Wrap(() =>
{
<span class="kwrd">throw</span> <span class="kwrd">new</span> Exception(<span class="str">"rollback please"</span>);
});
[DebuggerStepThrough]
<span class="kwrd">public</span> <span class="kwrd">class</span> Scope<TOuterAdvice, TInnerAdvice>
where TOuterAdvice : IAdvice, <span class="kwrd">new</span>()
where TInnerAdvice : IAdvice, <span class="kwrd">new</span>()
{
<span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">void</span> Wrap(Action body)
{
Scope<TOuterAdvice>.Wrap(()=> Scope<TInnerAdvice>.Wrap(body));
}
}
</pre>
<br />
All code in the article is simplified and real implementation is exercise for readers.
<br />
<br />
Enjoy :-)Zhttp://www.blogger.com/profile/02673125542713538726noreply@blogger.com0tag:blogger.com,1999:blog-8243961069707831485.post-9083896747136808032011-12-31T14:46:00.000+01:002012-01-02T10:27:19.087+01:00Fluentator - generate fluent API for your structuresWhen working with nested structures like configuration or XML it is bit of pain with syntax in C#. Consider this code below. The object initializes in C# 3.0 helped a lot, but it's still pretty far from ideal. Important point here is readability, which is achieved thru nesting the initializers.
<!-- code formatted by http://manoli.net/csharpformat/ -->
<pre class="csharpcode">
<span class="kwrd">var</span> model = <span class="kwrd">new</span> Model();
<span class="kwrd">var</span> pavel = <span class="kwrd">new</span> Employee(<span class="str">"Pavel"</span>);
model.Companies.Add(<span class="kwrd">new</span> Company(<span class="str">"Boldbrick & co."</span>)
{
Departments = <span class="kwrd">new</span> List<Department>
{
<span class="kwrd">new</span> Department(<span class="str">"Software & Visions"</span>, <span class="str">"swv"</span>)
{
Teams = <span class="kwrd">new</span> List<Team>
{
<span class="kwrd">new</span> Team(<span class="str">"Visions"</span>)
{
Employees = <span class="kwrd">new</span> List<Employee>
{
<span class="rem">// I was forced to move </span>
<span class="rem">// pavel variable declaration completely out of scope</span>
pavel,
<span class="kwrd">new</span> Employee(<span class="str">"Ondra"</span>),
},
IsAwesome = <span class="kwrd">true</span>,
},
<span class="kwrd">new</span> Team(<span class="str">"Developers"</span>)
{
Employees = <span class="kwrd">new</span> List<Employee>
(
<span class="rem">// I can't do any statements or declarations here</span>
<span class="rem">// to prepare my data in-place</span>
devNames.Select(n=><span class="kwrd">new</span> Employee(n))
)
{
<span class="rem">// note I can't add pavel first</span>
pavel,
}
}
}
}
}
});
</pre>
But there are downsides with approach above. You can't easily add same instance into 2 nodes. It forces you to declare pavel variable completely out of scope. And you can't use statements to prepare your data in place either. Note how Pavel is inserted after other employees into Developers team. The LINQ Select() helped great deal here, but it's not always possible to use it.
With more complex model and bigger tree to build, this will become unmanageable mess.
<p>
So, extension methods and lambdas to rescue. Do you like code below better ? I certainly do. I can use statements and variable declarations in inner scope. I get more dense and readable code.
<!-- code formatted by http://manoli.net/csharpformat/ -->
<pre class="csharpcode">
<span class="kwrd">var</span> model = <span class="kwrd">new</span> Model();
model.AddCompany(<span class="str">"Boldbrick & co."</span>, bb =>
{
bb.AddDepartment(<span class="str">"Software & Visions"</span>, <span class="str">"swv"</span>, swv =>
{
<span class="rem">// variable is still bit out of scope, but not in the root scope</span>
<span class="kwrd">var</span> pavel = <span class="kwrd">new</span> Employee(<span class="str">"Pavel"</span>);
swv.AddTeam(<span class="str">"Visions"</span>, visions =>
{
visions.AddEmployee(pavel);
visions.AddEmployee(<span class="str">"Ondra"</span>);
visions.IsAwesome = <span class="kwrd">true</span>;
});
swv.AddTeam(<span class="str">"Developers"</span>, devs =>
{
devs.AddEmployee(pavel);
<span class="rem">// I can add more employees after Pavel</span>
devs.AddEmployees(devNames.Select(n => <span class="kwrd">new</span> Employee(n)), dev=>
{
dev.Age = 33;
});
<span class="rem">// and also can use any complex statement in-place</span>
<span class="kwrd">for</span> (<span class="kwrd">int</span> i = 0; i < devNames.Count; i++)
{
<span class="kwrd">int</span> ix=i;
devs.AddEmployee(devNames[i], dev =>
{
dev.Age = ix;
});
}
});
});
);});</pre>
<h3>How the extension method looks like ?</h3>
Below is extension method over external structure Department, which accepts same parameters as Team constructor. Inside is instance creations and adding to the collection.
Finally to allow the nesting of scopes, we pass the new instance to Action<> delegate.
<!-- code formatted by http://manoli.net/csharpformat/ -->
<pre class="csharpcode">
<span class="kwrd">static</span> <span class="kwrd">public</span> Team AddTeam(<span class="kwrd">this</span> Department self, <span class="kwrd">string</span> name, Action<Team> result = <span class="kwrd">null</span>)
{
<span class="kwrd">var</span> item = <span class="kwrd">new</span> Team(name);
self.Teams.Add(item);
<span class="kwrd">if</span> (result != <span class="kwrd">null</span>) result(item);
<span class="kwrd">return</span> item;
}
</pre>
<h3>Generate the extensions</h3>
The extension method above is nice and useful but it's quite boring to write it for each combination of container and child item. Multiplied by all constructor signatures.
So I decided to create <b>ReflectionFluentator</b> which can generate the code for you. It reads your model via reflection and generates the C# extensions.
See <a href="http://code.google.com/p/polyglottos/source/browse/trunk/polyglottos.test/src/ReflectionFluentatorTest.cs#39">sample</a> how to use the generator.
<p> And the same thing for XML ? Sure.
You provide the <a href="http://code.google.com/p/polyglottos/source/browse/trunk/demomodel/library.xsd">XSD</a> to <b>XsdFluentator</b>.
See <a href="http://code.google.com/p/polyglottos/source/browse/trunk/polyglottos.test/src/XsdFluentatorTest.cs">sample</a> how to use the generator.
<!-- code formatted by http://manoli.net/csharpformat/ -->
<pre class="csharpcode">
<span class="kwrd">var</span> doc=<span class="kwrd">new</span> XDocument();
doc.AddLibrary(<span class="str">"Prague"</span>,prague =>
{
prague.AddBook(<span class="str">"Saturnin"</span>, book =>
{
book.AddAuthor(<span class="str">"Zdenek Jirotka"</span>);
});
prague.AddBook(<span class="str">"Bylo Nas 5"</span>, book =>
{
book.AddAuthor(<span class="str">"Karel Polacek"</span>);
});
});
</pre>
This code can generate this XML as expected.
<!-- code formatted by http://manoli.net/csharpformat/ -->
<pre class="csharpcode">
<span class="kwrd"><</span><span class="html">library</span> <span class="attr">id</span><span class="kwrd">="Prague"</span>
<span class="attr">xmlns</span><span class="kwrd">="http://polyglottos.googlecode.com/svn/trunk/demomodel/library.xsd"</span><span class="kwrd">></span>
<span class="kwrd"><</span><span class="html">book</span> <span class="attr">name</span><span class="kwrd">="Saturnin"</span><span class="kwrd">></span>
<span class="kwrd"><</span><span class="html">author</span> <span class="attr">name</span><span class="kwrd">="Zdenek Jirotka"</span> <span class="kwrd">/></span>
<span class="kwrd"></</span><span class="html">book</span><span class="kwrd">></span>
<span class="kwrd"><</span><span class="html">book</span> <span class="attr">name</span><span class="kwrd">="Bylo Nas 5"</span><span class="kwrd">></span>
<span class="kwrd"><</span><span class="html">author</span> <span class="attr">name</span><span class="kwrd">="Karel Polacek"</span> <span class="kwrd">/></span>
<span class="kwrd"></</span><span class="html">book</span><span class="kwrd">></span>
<span class="kwrd"></</span><span class="html">library</span><span class="kwrd">></span>
</pre>
Note that both generators are more prototypes than ready to ship. They don't handle any edge scenarios when reading the metadata or writing the code.
Fluentator is part of <a href="http://code.google.com/p/polyglottos/">Polyglottos</a> project. If you like the idea and wish to contribute improvements, please talk back.
<p>At this point some of you may wonder what else could be made fluent this way. In my case, I realized that I need to generate the code and the code is just nested structure. So I created CodeDom code generator <a href="http://code.google.com/p/polyglottos/">Polyglottos</a> with fluent API. That's for another article next year. Enjoy the party tonight!Zhttp://www.blogger.com/profile/02673125542713538726noreply@blogger.com0tag:blogger.com,1999:blog-8243961069707831485.post-45576352450924052612011-09-19T23:08:00.006+02:002011-09-19T23:16:29.692+02:00jni4net 0.8.6 - release<h3>Changes</h3>
<ul>
<li>fixed permission demand for sandboxed environments</li>
<li>improved proxygen can't find class reporting</li>
<li>improved the way we are looking for jni4net.j-xxx-.jar (while installed in GAC)</li>
<li><a href="http://code.google.com/p/jni4net/issues/detail?id=27">[#27]</a> - fixed build script problems</li>
</ul>
Download <a href="http://sourceforge.net/projects/jni4net/files/0.8.6/jni4net-0.8.6.0-bin.zip/download">here</a><br/><br/>
<h3>Road map</h3>
May people asked for road map. <a href="https://docs.google.com/document/pub?id=1J6ZAeYjn0x63osecI1L7sDohZ1qVA3mDPjk2Z4Zwh-U">This is my vision</a>, not a promise.Zhttp://www.blogger.com/profile/02673125542713538726noreply@blogger.com2tag:blogger.com,1999:blog-8243961069707831485.post-71564265769629434702011-08-17T20:12:00.002+02:002011-08-17T20:17:57.465+02:00jni4net 0.8.5 - release<h3>Changes</h3>
<ul>
<li><a href="http://code.google.com/p/jni4net/issues/detail?id=9">[# 9]</a> - support for indexer properties [by Johannes Rudolph]</li>
<li><a href="http://code.google.com/p/jni4net/issues/detail?id=9">[#22]</a> - Potential field name clash due to increasing numbering strategy of field names</li>
<li><a href="http://code.google.com/p/jni4net/issues/detail?id=9">[#24]</a> - Change of current directory during init may disrupt other code running in parallel</li>
<li><a href="http://code.google.com/p/jni4net/issues/detail?id=9">[#25]</a> - DirectByteBuffer doesn't work with Java 7</li>
</ul>
Download <a href="http://sourceforge.net/projects/jni4net/files/0.8.5/jni4net-0.8.5.0-bin.zip/download">here</a>Zhttp://www.blogger.com/profile/02673125542713538726noreply@blogger.com0tag:blogger.com,1999:blog-8243961069707831485.post-88762947395675880652011-07-18T11:07:00.032+02:002016-05-04T22:52:31.507+02:00Host your own Roborumble serverThere are several reasons why you might want to run your own Roborumble server. Maybe you would like to run small local contest at your school or workplace. Or maybe you are testing your new shiny robot. Or may you want to collect some battle data, like myself.
<br/><br/>
The <a href="http://darkcanuck.net/rumble/Rankings?game=roborumble">current Roborumble server</a> is created and maintained by <a href="http://robowiki.net/wiki/Darkcanuck">Darkcanuck</a>. Luckily he shares the <a href="http://darkcanuck.net/svn/rumbleserver/trunk/">RumbleServer sources</a> via subversion. It is implemented in PHP and MySQL.
<br/><br/>
Because I'm not PHP+MySQL expert, easiest solution for me was to download <a href="http://www.turnkeylinux.org/lampstack">ready-made LAMP</a> virtual machine and configure it.
<br/>
I know you are busy ;-), so I published my virtual appliance, you could just start using it. You can <a href="http://ane-kolin.cz/zamboch/turnkey-roborumble.2011-07-18.zip.torrent">download</a> it and run it in VMWare Player. Password is <span style="font-weight:bold;">robocode</span>, you should change it as soon. Or you could follow the guide below.
<br/><br/>
<h3>Configure server</h3>
Once you have <a href="http://www.turnkeylinux.org/lampstack">LAMP stack</a> up and running you need few things:
<br/> Install subversion client
<br/> Get PHP sources
<br/> Configure RumbleServer
<br/> Turn on URL rewriting mod in Apache
<br/> Configure MySQL database and grant permissions
<br/><br/>The appliance has could be configured from web admin. You can access it on https://192.168.1.12/ where 192.168.1.12 is the IP address assigned to the virtual machine by your DHCP server. I will use 192.168.1.12 which was assigned to me in rest of the article.
<br/><br/>
<br/> <span style="font-weight:bold;">Webmin</span>->Global configuration
<br/> ->Configure Apache Modules->rewrite: switch ON
<br/>
<br/> <span style="font-weight:bold;">MyPhpAdmin</span>
<br/> Create database->roborumble
Import script <a href="http://darkcanuck.net/svn/rumbleserver/trunk/schema/schema.sql">schema/schema.sql</a>
<br/> Priviledges->add new user->
<br/> name->rumbleuser
<br/> pass->rumblepass
<br/> Database for user->None
<br/> Global privileges->Select+Update+Insert+Delete
<br/>
<br/>
<span style="font-weight:bold;">On root shell</span> do something like this
<pre style="background-color: #CCCCCC">
apt-get install subversion
cd /var/www/
mkdir rumble
cd rumble
svn co http://darkcanuck.net/svn/rumbleserver/trunk/ .
chmod g+w templates_c/
chown :www-data templates_c/
cat > participants.txt
<span style="font-weight:bold;"><span style="font-style:italic;">[paste <a href="http://ane-kolin.cz/zamboch/participants.txt">participants.txt</a> file and press Ctrl-D]</span></span>
cd config
cp config.php-sample config.php
</pre>
<br/><br/>
<h3>Participants</h3>
Are defined as list of robots and their .jar files. Big competition is driven by <a href="http://robowiki.net/wiki/RoboRumble/Participants?action=raw">this file</a>. We could simplify our own list like <a href="http://ane-kolin.cz/zamboch/participants.txt">this</a>. We host the file on the appliance in folder /var/www/. So create you own shortlist and update it there. Note there are starting and ending tags.
<pre style="font-size:xx-small; background-color: #CCCCCC">
----
<pre>
jk.mega.DrussGT 2.0.4,http://www.minifly.rchomepage.com/robocode/jk.mega.DrussGT_2.0.4.jar
voidious.Diamond 1.5.34b,http://www.dijitari.com/void/robocode/voidious.Diamond_1.5.34b.jar
</pre>
----
</pre>
<br/><br/>
<h3>Configure client</h3>
Download and install <a href="http://sourceforge.net/projects/robocode/files/robocode/1.7.3.0/robocode-1.7.3.0-setup.jar/download">Robocode 1.7.3</a>
<br/>Edit c:\robocode\roborumble\roborumble.txt
<div style="font-size:xx-small;">
<br/> PARTICIPANTSURL=http://192.168.1.12/participants.txt
<br/> UPDATEBOTSURL=http://192.168.1.12/rumble/RemoveOldParticipant
<br/> RESULTSURL=http://192.168.1.12/rumble/UploadedResults
<br/> RATINGS.URL=http://192.168.1.12/rumble/RatingsFile
<br/> ITERATE=YES
</div>
<br/>start c:\robocode\roborumble.bat
<br/><br/>
<h3>Purge data</h3>
If you need to purge the data from the <span style="font-weight:bold;">roborumble</span> database and start from scratch just delete rows using MyPhpAdmin.
<pre style="font-size:xx-small; background-color: #CCCCCC">
delete from battle_results;
delete from game_pairings;
delete from bot_data;
delete from participants;
delete from upload_stats;
delete from upload_users;
</pre>
<span style="font-weight:bold;"><br/><br/>Oh, and once you are done with your local competition, don't forget to redirect back to <a href="https://literumble.appspot.com">official RoboRumble server</a> and contribute your CPU power!</span>
<br/><br/><a href="http://ane-kolin.cz/zamboch/turnkey-roborumble.2011-07-18.zip.torrent">Download turnkey-roborumble.2011-07-18.zip</a>.torrentZhttp://www.blogger.com/profile/02673125542713538726noreply@blogger.com1tag:blogger.com,1999:blog-8243961069707831485.post-70264306738540878632011-07-07T21:08:00.011+02:002011-07-07T21:36:27.235+02:00HowTo: Pass build property from TeamCity into Freemaker email notification templateThere is no magic, once you know it. My use-case was to prefix build number with configurable text before sending an email. The text was represented as TeamCity property <span style="font-style:italic;">system.tc.branch.number</span> in my case.
<br/><br/><a href="http://confluence.jetbrains.net/display/TCD65/Customizing+Notifications">TeamCity email templates</a> are implemented with <a href="http://freemarker.sourceforge.net/">Freemaker</a>. The TeamCity exposes all build properties as hash table on <a href="http://javadoc.jetbrains.net/teamcity/openapi/current/jetbrains/buildServer/serverSide/SBuild.html#getBuildOwnParameters%28%29">SBuild.getBuildOwnParameters()</a>.
<br/><br/>In the template the instance of SBuild is accessible under <span style="font-weight:bold;">build</span> variable.
Freemaker allows calling bean properties, in our case it would be <span style="font-weight:bold;">build.buildOwnParameters</span>, <a href="http://freemarker.sourceforge.net/docs/pgui_datamodel_objectWrapper.html">map lookup</a> thru square-bracket syntax <span style="font-weight:bold;">[]</span> and literals are enclosed in apostrophes.
<br/><br/>
<pre style="font-size:xx-small; background-color: #CCCCCC">
#${build.buildOwnParameters['system.tc.branch.number']}.${build.buildNumber}
</pre>Zhttp://www.blogger.com/profile/02673125542713538726noreply@blogger.com1tag:blogger.com,1999:blog-8243961069707831485.post-67718764140575459322011-06-28T21:48:00.008+02:002011-06-28T22:41:48.870+02:00jni4net 0.8.4 - release<h3>Changes</h3>
<ul>
<li>Added ability to load proxies into specified classLoader by Jose Chillan.
<br/><small>Bridge.LoadAndRegisterAssemblyFromClassLoader(File, ClassLoader)</small></li>
<li>JNIEnv.DetachCurrentThread() contributed by Renier B.</li>
<li>Bridge.setClrVersion() made static by Leonid Bogdanov</li>
</ul>
Download <a href="http://sourceforge.net/projects/jni4net/files/0.8.4/jni4net-0.8.4.0-bin.zip/download">here</a>Zhttp://www.blogger.com/profile/02673125542713538726noreply@blogger.com0tag:blogger.com,1999:blog-8243961069707831485.post-44066770489893114762011-03-26T15:03:00.024+01:002011-12-05T22:34:33.163+01:00Raising Property Changed fast and safe - yet another solutionThis Thursday we discussed with my colleagues how to raise property changed event. We learned that it could be done <br />
a) via string literal, <br />
b) via lambda expression tree, <br />
c) via StackTrace or MethodBase.GetCurrentMethod(). <br />
<a href="http://csharperimage.jeremylikness.com/2010/12/jounce-part-8-raising-property-changed.html">Nice summary is here.</a> or <a href="http://compositeextensions.codeplex.com/discussions/53731">here</a> <p>We did some naive performance test and learned that for 500k iterations on simple property, there is big difference in speed. <br />
a) is really fast, 13ms <br />
b) is slow, 1417ms, I guess because security checks apply for every call and every stack frame, and can't be fired from other properties. <br />
c) is slow, 2518ms, very slow, because expression tree is constructed for every call <p>So we played with it for a while and I invented solution with anonymous type (at botom). <p><span style="font-weight:bold;">Update 27.3.2011: </span>I was so focused on speed that I didn't realized that the solution yesterday didn't work nicely for rename. What a shame. I hope people give me another chance today. Here we have postponed creation of the expression tree, it takes about 75ms. And this time my ReSharper renames it correctly :-)<br />
<span style="font-weight:bold;">Update 5.12.2011: </span> As Alex noted in comments, there was thread safety issue with Dictionary. The code is now fixed with Hashtable instead.<br />
<br />
<!-- code formatted by http://manoli.net/csharpformat/ --><br />
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">abstract</span> <span class="kwrd">class</span> ModelBase : INotifyPropertyChanged
{
<span class="kwrd">public</span> <span class="kwrd">event</span> PropertyChangedEventHandler PropertyChanged;
<span class="kwrd">private</span> <span class="kwrd">static</span> <span class="kwrd">readonly</span> Hashtable Names = <span class="kwrd">new</span> Hashtable();
<span class="kwrd">protected</span> <span class="kwrd">void</span> RaisePropertyChange(Func<<span class="kwrd">string</span>> key)
{
<span class="kwrd">if</span> (PropertyChanged != <span class="kwrd">null</span>)
{
var propertyName = (PropertyChangedEventArgs)Names[key];
<span class="kwrd">if</span> (propertyName==<span class="kwrd">null</span>)
{
propertyName = <span class="kwrd">new</span> PropertyChangedEventArgs(key());
<span class="kwrd">lock</span> (Names)
{
Names[key] = propertyName;
}
}
PropertyChanged(<span class="kwrd">this</span>, propertyName);
}
}
<span class="kwrd">protected</span> <span class="kwrd">static</span> <span class="kwrd">string</span> Reg<T>(Expression<Func<T>> property)
{
<span class="kwrd">return</span> (property.Body <span class="kwrd">as</span> MemberExpression).Member.Name;
}
}
<span class="kwrd">public</span> <span class="kwrd">class</span> Model : ModelBase
{
<span class="kwrd">private</span> <span class="kwrd">string</span> firstName2;
<span class="kwrd">public</span> <span class="kwrd">string</span> FirstName2
{
get { <span class="kwrd">return</span> firstName2; }
set
{
firstName2 = <span class="kwrd">value</span>;
<span style="background-color: yellow;">RaisePropertyChange(() => Reg(() => FirstName2));</span>
}
}
}</pre><br />
<p><span style="font-weight:bold;">Doesn't work: </span>The lambda just helps to define the type without creating the instance and calling the getter. It takes about 77ms for half million calls. <!-- code formatted by http://manoli.net/csharpformat/ --> <pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">abstract</span> <span class="kwrd">class</span> ModelBase : INotifyPropertyChanged
{
<span class="kwrd">public</span> <span class="kwrd">event</span> PropertyChangedEventHandler PropertyChanged;
<span class="kwrd">private</span> <span class="kwrd">static</span> <span class="kwrd">readonly</span> Dictionary<Type, PropertyChangedEventArgs> Names =
<span class="kwrd">new</span> Dictionary<Type, PropertyChangedEventArgs>();
<span class="kwrd">protected</span> <span class="kwrd">void</span> RaisePropertyChange<T>(Func<T> f)
{
<span class="kwrd">if</span> (PropertyChanged!=<span class="kwrd">null</span>)
{
var key = <span class="kwrd">typeof</span>(T);
PropertyChangedEventArgs evntArgs;
<span class="kwrd">if</span> (!Names.TryGetValue(key, <span class="kwrd">out</span> evntArgs))
{
var propertyName = key.GetProperties()[0].Name;
evntArgs = <span class="kwrd">new</span> PropertyChangedEventArgs(propertyName);
<span class="kwrd">lock</span>(Names)
{
Names[key] = evntArgs;
}
}
PropertyChanged(<span class="kwrd">this</span>, evntArgs);
}
}
}
<span class="kwrd">public</span> <span class="kwrd">class</span> Model : ModelBase
{
<span class="kwrd">private</span> <span class="kwrd">string</span> firstName;
<span class="kwrd">public</span> <span class="kwrd">string</span> FirstName
{
get { <span class="kwrd">return</span> firstName; }
set {
<span class="kwrd">if</span> (firstName != <span class="kwrd">value</span>)
{
firstName = <span class="kwrd">value</span>;
<span style="background-color: yellow;">RaisePropertyChange(() => <span class="kwrd">new</span> {FirstName});</span>
}
}
}
}</pre>Zhttp://www.blogger.com/profile/02673125542713538726noreply@blogger.com14tag:blogger.com,1999:blog-8243961069707831485.post-44380683872963941512011-02-20T13:15:00.005+01:002011-02-20T16:50:53.843+01:00jni4net 0.8.3 - release<h3>Changes</h3>
<ul>
<li>added support for <a href="https://www.ibm.com/developerworks/java/jdk/">IBM JRE</a></li>
<li>added <a href="http://www.jboss.org/drools">drools</a> sample</li>
<li>added BridgeSetup.IgnoreJavaHome</li>
<li>improved error logging during initialization</li>
</ul>
<h3>Blocked DLLs for CLR 4.0</h3>
If you download the distribution package on jni4net and unzip it via Windows Explorer, it will set the DLL security zone as untrusted. That will prevent CLR 4.0 from loading the DLL and you will receive exception while initializing jni4net from Java side.
<br/>
The message states:
<br/>
<pre style="font-size:xx-small">
Can't init BridgeExport:An attempt was made to load an assembly from a network l
ocation which would have caused the assembly to be sandboxed in previous version
s of the .NET Framework. This release of the .NET Framework does not enable CAS
policy by default, so this load may be dangerous. If this load is not intended t
o sandbox the assembly, please enable the loadFromRemoteSources switch. See http
://go.microsoft.com/fwlink/?LinkId=155569 for more information.</pre>
<br/>
You can solve it by unblocking the DLLs.
<br/><span style="font-weight:bold;">Right-click on the files, open file properties and click unblock button.</span>
<br/>
<img src="http://pavel.savara.sweb.cz/pics/unblock.png">Zhttp://www.blogger.com/profile/02673125542713538726noreply@blogger.com0tag:blogger.com,1999:blog-8243961069707831485.post-40510082540984523942011-01-02T13:15:00.001+01:002011-01-02T14:30:54.001+01:00jni4net 0.8.2 - bugfix release<h3>Bug fixes</h3>
<ul>
<li>upgraded nMaven, NUnit, made build 32bit only</li>
<li>fixed throwing exceptions for missing proxy classes</li>
<li><a href="http://code.google.com/p/jni4net/issues/detail?id=18">[#18]</a> - C# string[]{null} -> JVM -> null reference exception</li>
<li>improved architecture detection</li>
</ul>Zhttp://www.blogger.com/profile/02673125542713538726noreply@blogger.com0tag:blogger.com,1999:blog-8243961069707831485.post-60750747945061014962010-11-07T18:15:00.005+01:002010-11-07T18:32:40.720+01:00jni4net 0.8.1 - bugfix release<ul>
<li>Fixed <a href="http://code.google.com/p/jni4net/issues/detail?id=17">memory leak</a> reported by Jaco Ackermann</li>
<li>Included improved CLR detection contributed by Leonid Bogdanov</li>
</ul>
Download <a href="https://sourceforge.net/projects/jni4net/files/0.8.1/jni4net-0.8.1.0-bin.zip/download">0.8.1 here</a>Zhttp://www.blogger.com/profile/02673125542713538726noreply@blogger.com0tag:blogger.com,1999:blog-8243961069707831485.post-38114617720445463422010-09-23T00:15:00.006+02:002010-09-23T01:00:10.925+02:00Decomposition in functional languagesGot an idea: functions (in FP) could be composed similar was as components in OOP. For example with dependency injection. For components in OOP we use interfaces. For functions we could use delegates. To achieve decomposition and modularity.
<br/>
I tried to find something about it. No luck. Probably because there are no functional programs big enough to need this ?
<br/>
While searching for enterprise scale applications written in FP I found this list.
<a href="http://homepages.inf.ed.ac.uk/wadler/realworld/">Functional Programming in the Real World</a> and <a href="http://view.samurajdata.se/ps.php?url=http%3A%2F%2Fcarpanta.dc.fi.udc.es%2Fpf%2Fpapers%2Fsigplan-angry.ps.gz&submit=View!">this paper</a>
<br/><br/>
I hope I just missed the killer application for FP, which would be big enough to deserve decomposition. Maybe someone could find me answer at <a href="http://stackoverflow.com/questions/3774224/decomposition-modularity-in-functional-languages">stack overflow</a>.Zhttp://www.blogger.com/profile/02673125542713538726noreply@blogger.com0tag:blogger.com,1999:blog-8243961069707831485.post-39085244636175083892010-07-20T22:25:00.010+02:002010-07-20T22:44:56.570+02:00CLR 4.0 for RobocodeI finally got motivated by <a href="http://www.beingnew.net/2010/07/continuing-battle-classes-for-robocode.html">Justin</a> and <a href="http://groups.google.com/group/robocode-developers/browse_thread/thread/e6654487cf2f3c5?hl=en">Jason</a> to do something for Robocode .NET again. I upgraded it to jni4net 0.8. This means Robocode will prefer CLR 4.0 if installed and then will run robots written in C# 4.0 or F#. I also implemented Robocode Control API for .NET. I piggyback to Flemming's working branch, hope he will not kill me once he returns from holidays :-D
<br/><br/>
Download preview is there, Alpha quality.<br/>
<a href="http://robocode.sourceforge.net/download/robocode-1.7.2.2-Alpha-setup.jar">robocode-1.7.2.2-Alpha-setup.jar</a>
<br/>
<a href="http://robocode.sourceforge.net/download/robocode.dotnet-1.7.2.2-Alpha-setup.jar">robocode.dotnet-1.7.2.2-Alpha-setup.jar</a>
<br/><br/>
<h3>MyFirstRobot.F#</h3>
I really like the syntax.<br/>
<pre style="font-size:x-small">
namespace SampleFs
open Robocode
type MyFirstRobot() =
inherit Robot()
override robot.Run() =
while true do
robot.TurnLeft(40.0)
robot.Ahead(20.0)
override robot.OnScannedRobot(evnt : ScannedRobotEvent) =
robot.Fire(1.0)
override robot.OnHitByBullet(evnt : HitByBulletEvent) =
robot.TurnLeft(90.0 - evnt.Bearing)
</pre>Zhttp://www.blogger.com/profile/02673125542713538726noreply@blogger.com0tag:blogger.com,1999:blog-8243961069707831485.post-89502776410526830822010-05-30T16:27:00.003+02:002010-05-30T16:39:20.002+02:00Learning F# with Project Euler - day 2<h3><a href="http://projecteuler.net/index.php?section=problems&id=4">Problem 4</a></h3>
<pre style="font-size:xx-small">
open Microsoft.FSharp.Core.Operators
let findpalindrome xs ys =
let separate s p = (s % (pown 10 (p+1))) - (s % (pown 10 p))
let shiftl s p o = (separate s p) / (pown 10 (p-o))
let shiftr s p o = (separate s p) * (pown 10 (o-p))
let flip f = shiftl f 5 0 + shiftl f 4 1 + shiftl f 3 2 + shiftr f 2 3 + shiftr f 1 4 + shiftr f 0 5
let findi xs y = xs |> Seq.filter( fun x -> (((x*y) = flip (x*y)) && (separate (x*y) 0 <> 0) ) ) |> Seq.map(fun x -> (x*y,x))
ys |> Seq.collect(fun y -> (findi xs y)) |> Seq.maxBy(fun t -> fst(t))
findpalindrome [100..999][100..999]
</pre>
<h3><a href="http://projecteuler.net/index.php?section=problems&id=5">Problem 5</a></h3>
<pre style="font-size:xx-small">
let test =
let max = (primes 20 |> Seq.reduce(fun a c -> a*c))*8L*3L
[1L..20L] |> Seq.filter(fun x -> (max % x) <> 0L)
</pre>
<h3><a href="http://projecteuler.net/index.php?section=problems&id=6">Problem 6</a></h3>
<pre style="font-size:xx-small">
let diff xs =
let sumsq = xs |> Seq.reduce(fun c a -> (a*a)+c)
let sum = (xs |> Seq.reduce(fun c a -> (a+c)))
let sqsum = sum*sum
sqsum - sumsq
diff [1..100]
</pre>
<h3><a href="http://projecteuler.net/index.php?section=problems&id=7">Problem 7</a></h3>
<pre style="font-size:xx-small">
open Microsoft.FSharp.Core.Operators
let primesnth nthprime =
let maxPrime = 300000
let pr : bool array = Array.zeroCreate maxPrime
let mutable res = 0
let mutable nth = 0
let mutable cur=2
while (nth < nthprime) do
if not pr.[cur] then
for wr in cur+cur .. cur .. maxPrime-1 do pr.[wr] <- true
res <- cur
nth <- nth + 1
cur <- cur + 1
res
primesnth 10001
</pre>Zhttp://www.blogger.com/profile/02673125542713538726noreply@blogger.com0tag:blogger.com,1999:blog-8243961069707831485.post-18336873034560432662010-05-28T01:49:00.006+02:002010-05-28T02:01:20.784+02:00Learning F# with projecteuler.netWow, lot of fun with <a href="http://projecteuler.net">projecteuler.net</a> !
<br/><br/>
<h3><a href="http://projecteuler.net/index.php?section=problems&id=1">Problem 1</a></h3>
<pre style="font-size:xx-small">
[1..999] |> Seq.filter( fun x -> (x % 3 = 0 || x % 5 = 0)) |> Seq.sum
</pre>
<h3><a href="http://projecteuler.net/index.php?section=problems&id=2">Problem 2</a></h3>
<pre style="font-size:xx-small">
let fib max =
let rec fibo a b max =
if b>= max then a :: [] else a :: fibo b (a+b) max
fibo 1 2 max
fib 4000000 |> Seq.filter(fun x -> (x % 2 = 0)) |> Seq.toList|> Seq.sum
</pre>
<h3><a href="http://projecteuler.net/index.php?section=problems&id=3">Problem 3</a></h3>
<pre style="font-size:xx-small">
open Microsoft.FSharp.Math
open System.Collections.Generic
let maxPrime:int= (int) (System.Math.Sqrt((float)600851475143I))
let primes maxPrime =
let pr : bool array = Array.zeroCreate maxPrime
let res = new List<bigint>()
for cur in 2 .. maxPrime/2 do
if not pr.[cur] then for wr in cur+cur .. cur .. maxPrime-1 do pr.[wr] <- true
for cur in 1 .. maxPrime-1 do
if not pr.[cur] then res.Add(new bigint(cur))
res
primes maxPrime |>
Seq.filter(fun x -> ((600851475143I % x) = 0I ))
|> Seq.map( fun x -> ((int)(x)))
|> Seq.max
</pre>Zhttp://www.blogger.com/profile/02673125542713538726noreply@blogger.com0tag:blogger.com,1999:blog-8243961069707831485.post-46714188779928244712010-04-17T22:24:00.005+02:002010-04-17T22:51:11.123+02:00jni4net NOT yet on Mono & LinuxI started with investigations of support for Mono on x86. The key problem is different calling convention - <span style="font-weight:bold;">cdecl</span>. My current implementation of JniLocalHandle is build on top of assumption that small structures are put onto stack same way as scalar types. But that's not valid assumption, it works just for stdcall. cdecl allocates the structure on heap and passes just pointer to the structure, no matter how big the structure is. Why I created JniLocalHandle ? Because I wanted to make strongly typed difference between JniLocalHandle and JniGlobalHandle. We could drop it and use IntPtr in order to deal with this problem. It will impact all generated proxies on C# side.<br/>
There is another problem with cdecl, because I need to put <pre>[UnmanagedFunctionPointer(CallingConvention.xxx)]</pre> on any JNI delegate. Example is JNIEnv.AllocObject. I think I'll need to duplicate whole JNIEnv class in order to avoid condition for each call.<br/>
Last small problem is with JNI.Dll which has the main <pre>[DllImport("jvm.dll", CallingConvention = CallingConvention.StdCall)]</pre>, it must be duplicated as well, because there is jvm.so on Linux. <br/><br/>
Currently I don't hear from people that they need Mono/Linux support for jni4net. If <span style="font-weight:bold;">you think you need it</span>, please <a href="http://groups.google.com/group/jni4net/browse_thread/thread/491e33083fd63a31?hl=en">tell us</a> the use case. I'm interested to hear why Mono support is worth of the effort. Till then I put it on ice.Zhttp://www.blogger.com/profile/02673125542713538726noreply@blogger.com5tag:blogger.com,1999:blog-8243961069707831485.post-20731404549758466302010-04-17T21:55:00.006+02:002010-04-17T22:33:38.159+02:00jni4net version 0.8 for .NET 4.0<ul>
<li>added support for CLR v 4.0</li>
<li>v40 is now loaded by default if it could be found. You could set the version explicitly with Bridge.setClrVersion()</li>
<li><a href="http://code.google.com/p/jni4net/issues/detail?id=8">#8</a> added BridgeSetup.AddJVMOption(string)</li>
</ul>
Download <a href="https://sourceforge.net/projects/jni4net/files/0.8/jni4net-0.8.0.0-bin.zip/download">jni4net 0.8</a>Zhttp://www.blogger.com/profile/02673125542713538726noreply@blogger.com0tag:blogger.com,1999:blog-8243961069707831485.post-12276350240476025702010-03-03T03:58:00.002+01:002010-03-03T04:13:08.875+01:00jni4net 0.7.1 - small bugfix release<h3>Bug fixes</h3>
<ul>
<li><a href="http://code.google.com/p/jni4net/issues/detail?id=7&can=1">[#7]</a> - added ParPrimC2J(IntPtr)</li>
<li><a href="http://code.google.com/p/jni4net/issues/detail?id=5&can=1">[#5]</a> - Reading Java home location from the Windows registry (Contributed by Martin Matula), BridgeSetup extended with JavaHome, and improved JavaHome auto detection</li>
<li>fixed missing assembly version for jni4net.n.*.dll </li>
</ul>Zhttp://www.blogger.com/profile/02673125542713538726noreply@blogger.com0tag:blogger.com,1999:blog-8243961069707831485.post-37307202322634363542010-02-25T22:55:00.002+01:002010-02-25T23:12:35.459+01:00Robocode with C++/CLIRecently I spotted question if it's possible to create robot in C++. Here is the answer. Ok, I know, it's not like real C++ with pointers etc, this is managed version of C++, which is safe enough to be runnable in Robocode.
<ul>
<li>Download VS 2008 Express C++</li>
<li>Create new CLR-> Class Library (DLL) project</li>
<li>Go to project properties, Common Properties, Add New Reference, and add <span style="font-weight:bold;">robocode.dll</span> from lib folder of your robocode installation.</li>
<li>Go to project properties, Configuration properties, General, Common Language Runtime support and set it to Safe MSIL (/clrsafe)</li>
<li>Go to AssemblyInfo.cpp and delete line with [assembly:SecurityPermission(SecurityAction::RequestMinimum, UnmanagedCode = true)];</li>
<li>Go to [<span style="font-style:italic;">myCppRobot</span>].h and insert code below </li>
<li>Compile it, drop the DLL into Robocode and enjoy!</li>
</ul>
<!-- code formatted by http://manoli.net/csharpformat/ -->
<pre class="csharpcode">
<span class="preproc">#pragma</span> once
<span class="kwrd">using</span> <span class="kwrd">namespace</span> System;
<span class="kwrd">using</span> <span class="kwrd">namespace</span> Robocode;
<span class="kwrd">namespace</span> myCppR {
<span class="kwrd">public</span> <span class="kwrd">ref</span> <span class="kwrd">class</span> MyCplusplusRobot : Robot {
<span class="kwrd">public</span>:
<span class="kwrd">virtual</span> <span class="kwrd">void</span> Run() <span class="kwrd">override</span> {
<span class="kwrd">while</span>(<span class="kwrd">true</span>) {
Ahead(100);
TurnLeft(100);
}
}
};
}
</pre>Zhttp://www.blogger.com/profile/02673125542713538726noreply@blogger.com2tag:blogger.com,1999:blog-8243961069707831485.post-53579211316852168442010-02-15T23:49:00.002+01:002010-02-16T00:05:03.245+01:00Robocode .NET - 1.7.2 public betaThis <a href="http://robo-code.blogspot.com/2010/02/robocode-1720-beta-net-robots-are-now.html">release</a> of Robocode is big <a href="http://robo-code.blogspot.com/2010/02/robocode-net-introduction.html">achievement</a> for me.Zhttp://www.blogger.com/profile/02673125542713538726noreply@blogger.com0tag:blogger.com,1999:blog-8243961069707831485.post-57802530849960791322010-02-13T23:41:00.006+01:002010-02-14T01:28:25.207+01:00jni4net version 0.7 released<h3>support for delegates and events</h3>
.NET events and delegates are supported by proxygen and runtime. From Java side they could be invoked with Invoke() method which has proper signature. Delegates could be also implemented on Java side, by usual anonymous class and passed back to CLR. So Java could subscribe to .NET events.
<!-- code formatted by http://manoli.net/csharpformat/ -->
<pre class="csharpcode">
<span class="kwrd">this</span>.button1.addClick(<span class="kwrd">new</span> system.EventHandler(){
<span class="kwrd">public</span> <span class="kwrd">void</span> Invoke(system.Object sender, system.EventArgs e){
button1.setText(<span class="str">"Clicked"</span>);
}
});
</pre>
Full code is in <a href="http://code.google.com/p/jni4net/source/browse/trunk/content/samples/winforms/java/TestForm.java">winforms sample</a>, which is part of binaries.
<br/><br/>
<h3>Other changes</h3>
<ul>
<li>solved problem with spaces in path to dll/jar</li>
<li>assembly loading now uses java.io.File or assembly name (breaking change)</li>
<li>static class is no longer found by name, attribute parameter added (breaking change)</li>
</ul>
Download <a href="https://sourceforge.net/projects/jni4net/files/">there</a>Zhttp://www.blogger.com/profile/02673125542713538726noreply@blogger.com0tag:blogger.com,1999:blog-8243961069707831485.post-5286613468327081592010-01-24T01:32:00.006+01:002010-01-24T13:38:15.097+01:00jni4net version 0.6 released<ul>
<li>Implemented <span style="font-weight:bold;">out</span> and <span style="font-weight:bold;">ref</span> parameter from C#</li>
<a href="http://msdn.microsoft.com/en-us/library/ch92fbc1.aspx">DateTime.TryParse</a> has second parameter 'out'. This is how to use it from Java:
<br/>
<!-- code formatted by http://manoli.net/csharpformat/ -->
<pre class="csharpcode">
Out<DateTime> dt=<span class="kwrd">new</span> Out<DateTime>();
<span class="kwrd">if</span> (DateTime.TryParse(<span class="str">"2009-08-28"</span>,dt)){
System.<span class="kwrd">out</span>.println(dt.getValue());
}
</pre>
<br/>
<li>Improved proxygen to not generate virtual method overrides</li>
<li>Eliminated lot of warnings in generated code</li>
<li>Strongly typed JNI references (this is breaking change, please regenerate your proxies)</li>
<li>Sun specific DirectBufferCleaner, which holds the reference to pinned buffer</li>
<li>Native methods unregistration when appdomain unloads</li>
<li>Switched off signed .jar, because it prevents other people generating (unsigned) proxies into same packages. For example java.util_</li>
<li>Possibility to specify alternate classloader</li>
<li>Declarative security for running in partially trusted environments</li>
<li>JVM exceptions are serializable for CLR binary serialization</li>
</ul>
Download <a href="https://sourceforge.net/projects/jni4net/files/">there</a>Zhttp://www.blogger.com/profile/02673125542713538726noreply@blogger.com0tag:blogger.com,1999:blog-8243961069707831485.post-49524947244104975152010-01-09T16:30:00.009+01:002010-02-13T14:57:28.070+01:00Robocode .NET - alpha bitsI'm proud to present working version of .NET Robocode for community testing.
It took me almost exactly 2 years.<br/><br/>
<h3>Prerequisites</h3>
<ul>
<li>make sure you have .NET framework >= 2.0 installed on your windows box</li>
<li>backup your robocode home</li>
</ul>
<h3>Install and start</h3>
<ul>
<li>Download <a href="http://robocode.sourceforge.net/download/robocode-1.7.3.0-setup.jar">robocode-1.7.3.0-setup.jar</a> and <a href="http://robocode.sourceforge.net/download/robocode.dotnet-1.7.3.0-setup.jar">robocode.dotnet-1.7.3.0-setup.jar</a></li>
<li>run robocode-1.7.3.0-setup.jar</li>
<li>run robocode.dotnet-1.7.3.0-setup.jar</li>
<li>start robocode.bat</li>
<li>start new battle with samplecs.MyCsTeam and samplecs.PaintingRobot</li>
<li>open samplecs.PaintingRobot dialog and enable painting</li>
</ul>
<h3>Optional</h3>
<ul>
<li>start your Visual Studio</li>
<li>open robots/samplescs/samplescs.csproj</li>
<li>or create project new and reference <b>robocode.dll</b> from libs\ (Robot API for .NET)</li>
<li>and code your own .NET robot :-D</li>
</ul>
Please try it and say what you think !<br/><br/>
<h3>Known gaps</h3>
<ul>
<li>Robot API xml documentation is not yet ready</li>
<li>IGraphics/onPaint have just simple operations implemented</li>
<li>Robot could create unlimited threads, (but could not cause any harm to your computer)</li>
<li>jni4net 0.6 was not released public yet</li>
<li>Few unit tests still fail</li>
</ul>
<p>
These binaries above are 1.7.3, but that was just working number. We will merge it to trunk and release as 1.7.2 probably.
Sources are <a href="http://code.google.com/p/robocode/source/browse/#svn/robocode/trunk/plugins/dotnet">in trunk</a> already.
</p>
<br/>Enjoy!Zhttp://www.blogger.com/profile/02673125542713538726noreply@blogger.com3