I see no cogent reason for implementing Identifiable for each fact class.<br>The hashCode() any object returns should be distinct enough, especially<br>considering that all the hash codes are munched together, which is<br>
definitely not *guaranteed* to result in different values for *all* rule and<br>fact set combinations. <br><br>But please do as Greg suggested.<br><br>BTW, it&#39;s sufficient to end with<br>  return alreadyActivatedRules.add(hash);<br>
<br>-W<br><br>On Thu, Oct 8, 2009 at 11:43 PM, Dave Schweisguth <span dir="ltr">&lt;<a href="mailto:dave@schweisguth.org">dave@schweisguth.org</a>&gt;</span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Greetings fellow Droolers,<br>
<br>
Each of our rules modifies the fact it matches. We&#39;d like to run each of<br>
those rules exactly once, not reactivating them when a fact changes. I see<br>
from the archives that I&#39;m not the first person to discover that no-loop is<br>
too weak and lock-on-activate too strong for my purposes.<br>
<br>
I implemented our requirement with an AgendaListener that remembers hashes<br>
of rules + facts. This works but requires each fact to implement an<br>
interface with a method that returns the hash, and means TWO casts each time<br>
I examine a FactHandle. The whole AgendaFilter is below so you can see what<br>
I mean.<br>
<br>
Can anyone suggest a better way? I&#39;m looking more for a better approach<br>
altogether than I am for critique of the implementation of my current<br>
approach, although the latter would not be unwelcome.<br>
<br>
private static class Once<br>
    implements AgendaFilter {<br>
<br>
    private final Set&lt;Integer&gt; alreadyActivatedRules = new HashSet&lt;Integer&gt;();<br>
<br>
    public boolean accept(Activation activation) {<br>
        int hash = activation.getRule().getName().hashCode();<br>
        for (FactHandle handle: activation.getFactHandles()) {<br>
            Object object = ((DefaultFactHandle) handle).getObject();<br>
            hash *= 31;<br>
            if (object instanceof Identifiable) {<br>
                hash += ((Identifiable) object).getIdentity();<br>
            } else if (object instanceof String) {<br>
                // We get here when a rule uses from on a string collection<br>
                hash += object.hashCode();<br>
            } else {<br>
                throw new IllegalStateException(<br>
                    &quot;Don&#39;t know what to do with fact class &quot;<br>
                        + object.getClass() + &quot;, value &quot; + object);<br>
            }<br>
        }<br>
        boolean accept = !alreadyActivatedRules.contains(hash);<br>
        alreadyActivatedRules.add(hash);<br>
         return accept;<br>
    }<br>
<br>
}<br>
<br>
Thanks &amp; cheers,<br>
<font color="#888888"><br>
--<br>
| Dave Schweisguth                           <a href="http://schweisguth.org/%7Edave/" target="_blank">http://schweisguth.org/~dave/</a> |<br>
| Home: dave at <a href="http://schweisguth.org" target="_blank">schweisguth.org</a>            Work: <a href="http://www.nileguide.com/" target="_blank">http://www.nileguide.com/</a> |<br>
| For compliance with the NJ Right to Know Act: Contents partially unknown |<br>
_______________________________________________<br>
rules-users mailing list<br>
<a href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a><br>
<a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>
</font></blockquote></div><br>