[SOLVED] Question about executing groovy script from java

Hi

Probably I would better ask this on the Groovy forum but I thought asking it here I can get to answer quickly as I know some folks here already using groovy.

At the end of my groovy script, I have added

this as DialogManager

I am evaluating the script with ScriptEngine like this

DialogManager dialogManager = (DialogManager) scriptEngine.eval(script);

so I am supposing after evaluating the script, it returns an instance of the DialogManager interface. This is how the interface looks like

public interface DialogManager {

    public void initialize(EntityId npcId);

    public Optional<Dialog> createDialog(String topic, EntityId player);

    public void terminate();

}

I want to know if this returned dialogManager instance is already compiled and standalone java class or it will be evaluated by groovy every time I call a method on it?

Regards

When it’s returned it will be a Java class. It can’t really be otherwise, actually.

Groovy objects are real Java objects… in order to implement the interface that had to be real Java .class (in memory) definitions.

Edit: Note that when documentation says things like “groovy IS Java”… this is what they mean. It’s not interpreted.

1 Like

I see. Thanks for the quick answer.

For completeness, I feel it necessary to mention that compiled groovy code will sometimes run a little slower than the same Java code. Mostly not… but for example, method calls on untyped objects (duck typing) have to do a little bit of extra work to find the method to call.

Usually this is pretty fast and as I recall from looking at this years ago it tries to cache as much as it can with respect to lookups like that.

And for a dialog manager, it shouldn’t really matter at all. We’re talking microseconds difference.

Note: without knowing how you are using your DialogManager you might consider inverting things somewhat and having a central DialogManager that is in Java (or groovy) that you pass to your dialog scripts through a binding. They then register themselves with that manager. This has a few benefits, not the least of which is that you really could write some one-off Java dialog topics as well if it’s more convenient.

…but for the simple case of all dialogs being defined in one big groovy file then it probably doesn’t make sense.

1 Like

Thanks for the detailed info.

Make sense to have a central DialogManager and reusable dialogs. I will think more about it. :slightly_smiling_face:

In my current prototype, I have a script (dialog manager) for each NPC where I am writing all his dialogs in there.

For what it worth, this a super dummy test dialog manager for an NPC called old-man.

(No DSL stuff there)

package Maps.Map_1.Dialogs

import com.dalwiestudio.moona.plot.es.DialogManagerInfo
import com.dalwiestudio.moona.server.plot.Dialog
import com.dalwiestudio.moona.server.plot.DialogOption
import com.dalwiestudio.moona.server.plot.DialogPage
import com.dalwiestudio.moona.plot.es.DialogTopic
import com.dalwiestudio.moona.server.plot.DialogBuilder
import com.dalwiestudio.moona.server.plot.DialogManager
import com.dalwiestudio.moona.server.plot.PageFormatter
import com.dalwiestudio.moona.server.plot.PageTranslator
import com.dalwiestudio.moona.server.plot.Topic
import com.simsilica.es.EntityData
import com.simsilica.es.EntityId
import com.simsilica.es.Name

/**
 *
 * @author Ali-RS 
 */


EntityData getEd() { return entityData }

topicMap = new HashMap<>();
Map<String, Topic> getTopics() { return topicMap; }
Topic addTopic(Topic topic) {
    topics.put(topic.getName(), topic);
    return topic;
}

npcId = null;
EntityId getNpc() { return npcId }
void setNpc(EntityId npcId) { this.npc = npcId }

resourceName = null;
String getResourceName() {return  resourceName}
void setResourceName(String resourceBundle) {
    this.resourceName = resourceBundle;
}

void initialize(EntityId npcId) {
    this.npc = npcId
    this.resourceName = "Dialogs/" + ed.getComponent(npcId, DialogManagerInfo.class).getManagerName(ed)
    ed.setComponent(npc, new DialogTopic("Greeting"))
}

void terminate() { this.npc = null }

Optional<Dialog> createDialog(String topic, EntityId player) {
    Dialog dialog = null
    topics.get(topic).getDialogBuilders().stream()
            .findFirst()
            .ifPresent({ builder -> dialog = builder.build(npc, player) })
    return Optional.ofNullable(dialog)
}


Topic greeting = addTopic(new Topic("Greeting"))
greeting.addDialogBuilder(new DialogBuilder()
        .setVersion(1)
        .setBuildFunction({npc, player ->
            String playerName = ed.getComponent(player, Name.class).getName()
            Dialog dialog = new Dialog(1)
            dialog
                    .setPageTranslator(new PageTranslator(dialog.getId(), resourceName))
                    .addPage(new DialogPage(1, "Hi %s")
                        .setFormatter(new PageFormatter(playerName))
                        .addOption(new DialogOption(1, "Hello there!"))
                        .addOption(new DialogOption(2, "Go away!"))
                        .setPageHandler({option ->
                            DialogPage returnPage;
                            switch (option.getId()) {
                                case 1: returnPage = dialog.getPage(2); break
                                case 2: returnPage = dialog.getPage(3); break
                            }
                            return Optional.of(returnPage)
                        }))
                    .addPage(new DialogPage(2, "Nice to meet you!"))
                    .addPage(new DialogPage(3, "Why so sad?"))

            return dialog
        }))


this as DialogManager