Java动态编程触发器

Java动态编程触发器,java,dynamic,triggers,Java,Dynamic,Triggers,假设我想写动态代码: 魔兽争霸3触发系统: JAVA 问题: 如果代码是静态编写的,则此代码将运行,但不能动态生成。条件1,2要求其构造中有一个“特定单元”, 因此,它们不可能存储在内存中(因为它们无法创建)。这个问题的存在是因为: 条件1,2不知道它将在“for循环”中, 这两个变量都不表示该范围中存在变量“triggeringUnit” 为了解决这个问题,我应该创建一个包含范围内所有变量的hashmap吗 Hashmap变量=; 条件1=新的IsAliveCondition(“trigge

假设我想写动态代码:

魔兽争霸3触发系统: JAVA 问题: 如果代码是静态编写的,则此代码将运行,但不能动态生成。条件1,2要求其构造中有一个“特定单元”, 因此,它们不可能存储在内存中(因为它们无法创建)。这个问题的存在是因为: 条件1,2不知道它将在“for循环”中, 这两个变量都不表示该范围中存在变量“triggeringUnit”

为了解决这个问题,我应该创建一个包含范围内所有变量的hashmap吗


Hashmap变量=;
条件1=新的IsAliveCondition(“triggeringUnit”);
条件2=新的HasNameCondition(“triggeringUnit”);
条件=新的和条件(条件1,条件2);
//运行时
用于(单位触发单位:leveledUnits)
{
变量put(“triggeringUnit”,triggeringUnit);
if(condition.isTrue())
{
}
}


有更好的解决方案/设计模式吗?

它看起来有点像您正在寻找的。这些系统允许使用GUI或某种脚本制定规则,并且可以与语言(通常是java)接口,以便为规则提供更多功能,并允许程序调用规则引擎


最著名的免费开源BRM是。

通常这需要一些发布/订阅机制,或者GOF所称的。创建事件类型层次结构,并在发生任何事件时触发事件,让观察者订阅受支持的事件

这是初步的初稿:

interface EventListener<X extends EventType>{
    processEvent(Map<String, Object> data);
}

public class EventDispatcher{
    private Map<EventType, Collection<EventListener<?>> listeners; // initialize this
    public <X extends EventType> void addListener(X type, EventListener<X> listener){
        // add listener to map
    }
    public void dispatchEvent(EventType type, Map<String, Object> data){
        if(listeners.containsKey(type){
            for(EventListener<EventType> listener: listeners.get(type)){
                listener.processEvent(data);
            }
        }
    }
}
接口事件监听器{
processEvent(地图数据);
}
公共类事件调度器{

私有映射对于动态条件,您可以使用动态语言

class IsAliveCondition {
    def triggeringUnit

    boolean isCase() {
        triggeringUnit.alive
    }
}

class HasNameCondition {
    def triggeringUnit
    def name

    boolean isCase() {
        triggeringUnit.name == name
    }
}

class MyUnit {
    def alive
    def name
}

def condition = '''
new IsAliveCondition(triggeringUnit: triggeringUnit) && 
new HasNameCondition(triggeringUnit: triggeringUnit, name: 'somename').isCase()
'''

def leveledUnits = [new MyUnit(alive: true, name: 'somename'), new MyUnit(name: 'Joe')]

leveledUnits.each { triggeringUnit ->
    def shell = new GroovyShell(this.class.classLoader, new Binding([triggeringUnit: triggeringUnit]))
    if (shell.evaluate(condition)) {
        println "Condition for <$triggeringUnit.name> satisfied: $condition"
    }
}
class-IsAliveCondition{
def触发器
布尔isCase(){
活生生的
}
}
类HasNameCondition{
def触发器
定义名称
布尔isCase(){
triggeringUnit.name==名称
}
}
类别MyUnit{
def活着
定义名称
}
定义条件=“”
新的IsAliveCondition(triggeringUnit:triggeringUnit)和
新的HasNameCondition(triggeringUnit:triggeringUnit,名称:'somename')。isCase()
'''
def leveledUnits=[new MyUnit(alive:true,name:'somename'),new MyUnit(name:'Joe')]
leveledUnits.each{triggeringUnit->
defshell=newgroovyshell(this.class.classLoader,新绑定([triggeringUnit:triggeringUnit]))
if(外壳评估(条件)){
println“满足的条件:$Condition”
}
}
您知道,这里的条件只是硬编码的字符串。但它可以很容易地从文件中读取。
绑定
是您使用的一种哈希映射,但它是由Groovy提供的


当然,JVM还有很多其他动态语言:Jython、JRuby和JavaScript是主要的动态语言。它们通常与Java的通信相对简单。例如,
IsAliveCondition
hasnameCdition
也可以用Java编写(在这种情况下,他们需要构造函数、getter/setter以及类型信息)。

这个问题也更广泛。例如,如果我有处理100 dmg(静态)的能力,它可以被重写以引用hashmap的一个变量,因此用户可以修改它的功能。您可以研究使用脚本语言。Java附带了一系列用于集成它们的API和一个Javascript实现:但脚本语言与Java一样是静态的。我必须从开始时开始手动重写条件=code复制,在我以前的解决方案中,我将定义一组用于定义功能的基本条件,这些条件将从xml导入。我想我不太明白您要实现什么,我以为您想要一种处理一些用户定义触发器的方法。这只是您说的第一个想法“存储变量范围的hashmap”是“脚本语言就是这么做的”。此外,为什么您必须从一开始就重写条件?就像您在Java中提出
条件
对象一样,您可以在JS中使用常规函数。您可以通过编写/生成使用基本条件的JS来编写这些函数。
Hashmap<String, Object> variables = ... ;
   condition1 = new IsAliveCondition("triggeringUnit");
   condition2 = new HasNameCondition("triggeringUnit");
   condition = new AndCondition( condition1, condition2);

   //At Runtime
   for( Unit triggeringUnit : leveledUnits )
   {
      variables.put("triggeringUnit", triggeringUnit );
      if ( condition.isTrue() )
      {

      }
   }
interface EventListener<X extends EventType>{
    processEvent(Map<String, Object> data);
}

public class EventDispatcher{
    private Map<EventType, Collection<EventListener<?>> listeners; // initialize this
    public <X extends EventType> void addListener(X type, EventListener<X> listener){
        // add listener to map
    }
    public void dispatchEvent(EventType type, Map<String, Object> data){
        if(listeners.containsKey(type){
            for(EventListener<EventType> listener: listeners.get(type)){
                listener.processEvent(data);
            }
        }
    }
}
class IsAliveCondition {
    def triggeringUnit

    boolean isCase() {
        triggeringUnit.alive
    }
}

class HasNameCondition {
    def triggeringUnit
    def name

    boolean isCase() {
        triggeringUnit.name == name
    }
}

class MyUnit {
    def alive
    def name
}

def condition = '''
new IsAliveCondition(triggeringUnit: triggeringUnit) && 
new HasNameCondition(triggeringUnit: triggeringUnit, name: 'somename').isCase()
'''

def leveledUnits = [new MyUnit(alive: true, name: 'somename'), new MyUnit(name: 'Joe')]

leveledUnits.each { triggeringUnit ->
    def shell = new GroovyShell(this.class.classLoader, new Binding([triggeringUnit: triggeringUnit]))
    if (shell.evaluate(condition)) {
        println "Condition for <$triggeringUnit.name> satisfied: $condition"
    }
}