简体   繁体   English

将函数作为参数传递到对象列表

[英]Passing a function as a parameter onto a list of objects

So I am trying to make a basic game engine, based around the idea of tags, where every object has a bunch of tags that I can use to group things like wall segments and perform actions on them all at once. 因此,我正在尝试基于标签的概念创建一个基本的游戏引擎,其中每个对象都有一堆标签,我可以用它来分组像墙段这样的东西并一次对它们执行操作。 Since I don't want to have to surround every function with a loop to call it on each object, I am trying to make a method that can call the passed method on each object. 因为我不想用循环来围绕每个函数来在每个对象上调用它,所以我试图创建一个可以在每个对象上调用传递方法的方法。

here is some example suto-code: 这是一些示例suto-code:

//have a list of objs. some door, some not.

//an example of stuff I could want to do
//  - check returns on any functions called
//  - call a function on a bunch of objects, possibly with parameters
if (runOnTag("door", isClosed())[aPositionInReturnList] == true){
    runOnTag("door", open());
}

//the method
public couldBeAnyType[] runOnTag(String tag, function(anyPerams)){    //dont want the function to compile here
    for (String currentObj : listOfObjsWith[tag]){
        returns[index++] = currentObj.function(anyPerams);     //so that it can be executed on this object
    }
    return returns;    //want to be able to colect returns
}

I have already looked through a bunch of other answers to this type of question, but I don't understand what is going on in them. 我已经查看了这类问题的一些其他答案,但我不明白它们中发生了什么。 If anyone could explain it more simply, I would greatly appreciate it. 如果有人能够更简单地解释它,我会非常感激。

Assumption: you do not have objects that change tags dynamically. 假设:您没有动态更改标签的对象。

Why not implement your tags as interfaces? 为什么不将标签实现为接口? This is faster than string matching, type-safe and in general more efficient. 这比字符串匹配更快,类型安全且通常更有效。

interface Door {boolean isClosed(); void open();}

class State {
   private Collection<Object> gameObjects;

   public <T,R> Stream<R> onTagged(Class<T> type, Function<T,R> apply) {
      return gameObjects
           .stream()
           .filter(type::isInstance)
           .map(type::cast)
           .map(apply);
   }
}

Ignore the name ( onTagged ), make your own. 忽略名称( onTagged ),自己制作。 This can be used like this fe to find if there is any door open: 这可以像这样用来查找是否有任何门打开:

State state = ...;
if(state.onTagged(Door.class, door -> !door.isClosed()).anyMatch(Boolean.TRUE::equals)) {
  // ... do stuff ...
}

You will however find that it's usually better like this, because then you can compose operations (map/filter/any*) very easily: 然而,你会发现它通常更好,因为这样你就可以很容易地编写操作(map / filter / any *):

   public <T> Stream<T> withTag(Class<T> type) {
      return gameObjects
           .stream()
           .filter(type::isInstance)
           .map(type::cast);
   }

if(state.withTag(Door.class).anyMatch(door -> !door.isClosed())) {
  // ... do stuff ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM