Пример #1
0
  /**
   * Generates a metatable containing metafunctions for a given object type using the currently
   * registered {@link LuaObjectMeta}s.
   *
   * <p>This method will only generate one metatable per class type; the mapping of already made
   * metatables will not be cleared at any point during runtime. If a metatable had already been
   * generated, that metatable is returned.
   *
   * <p>It is possible for functions within each object meta to override each other when this method
   * generates a new metatable.
   *
   * <p>If there are no suitable meta objects for the provided object or none of the applicable meta
   * objects have any metafunctions to register, null is returned.
   *
   * @param obj the Object to generate a metatable for
   * @return the metatable for the given Object
   */
  public static LuaTable generateMetatable(Object obj) {
    LuaTable copyTable = Lua.METATABLES.get(obj.getClass());
    if (copyTable == null && copyTable != Lua.EMPTY_METATABLE) {
      LuaTable functable = new LuaTable();
      Lua.metas.clear();
      Lua.META.values().forEach(Lua.metas::add);
      Lua.PMETA.values().forEach(Lua.metas::add);

      Lua.metas.forEach(
          meta -> {
            if (meta.getTargetObjectClass().isInstance(obj) && meta.getMetatable() != null) {
              LuaUtil.iterateTable(
                  meta.getMetatable(),
                  vargs -> {
                    functable.set(vargs.arg(1), vargs.arg(2));
                  });
            }
          });

      Lua.metas.forEach(
          meta -> {
            meta.postMetaInit(functable);
          });

      if (LuaUtil.getTableSize(functable) > 0) {
        LuaTable metatable = new LuaTable();

        // add the object's metatable functions
        metatable.set("__index", functable);

        // add the stuff we do for every metatable
        GLOBAL_METATABLE
            .entries()
            .forEach(
                entry -> {
                  metatable.set(entry.key, entry.value);
                });

        Lua.METATABLES.put(obj.getClass(), metatable);
        copyTable = metatable;
      } else {
        Lua.METATABLES.put(obj.getClass(), Lua.EMPTY_METATABLE);
      }
    }

    if (copyTable != null && copyTable != Lua.EMPTY_METATABLE) {
      return LuaUtil.copyTable(copyTable, true);
    }

    return null;
  }
Пример #2
0
  static {
    metas = new ObjectSet<>();
    META = new ObjectMap<>();
    PMETA = new ObjectMap<>();
    METATABLES = new ObjectMap<>();
    GLOBAL_METATABLE = new ObjectMap<>();
    EMPTY_METATABLE = new LuaTable();

    // Metamethods implementation for all LuaObjectValues.

    GLOBAL_METATABLE.put(
        LuaValue.EQ.tojstring(),
        LuaUtil.asFunction(
            vargs -> {
              if (vargs.isnil(2)) {
                // We'll still get called for nil. Automagically return false for nil.
                return LuaValue.valueOf(false);
              }

              // obj1, us, is guaranteed to be an object value
              LuaObjectValue<? super Object> obj1 = (LuaObjectValue<? super Object>) vargs.arg(1);
              LuaValue obj2 = vargs.arg(2);

              if (obj2 instanceof LuaObjectValue) {
                return LuaValue.valueOf(
                    obj1.getObject() == ((LuaObjectValue<? super Object>) obj2).getObject());
              }

              return LuaValue.valueOf(false);
            }));

    loadMeta(LuaAudioDataMeta.class);
    loadMeta(LuaAudioMeta.class);
    loadMeta(LuaAudioPlayableMeta.class);
    loadMeta(LuaColliderMeta.class);
    loadMeta(LuaColorMeta.class);
    loadMeta(LuaDestructibleMeta.class);
    loadMeta(LuaEnvironmentMeta.class);
    loadMeta(LuaEventListenerMeta.class);
    loadMeta(LuaFontMeta.class);
    loadMeta(LuaIdentifiableMeta.class);
    loadMeta(LuaInputDataMeta.class);
    loadMeta(LuaLayerableMeta.class);
    loadMeta(LuaMusicMeta.class);
    loadMeta(LuaOverworldControllerMeta.class);
    loadMeta(LuaPositionableMeta.class);
    loadMeta(LuaPressDataMeta.class);
    loadMeta(LuaProcessableMeta.class);
    loadMeta(LuaRenderableMeta.class);
    loadMeta(LuaSchedulerMeta.class);
    loadMeta(LuaSoundDataMeta.class);
    loadMeta(LuaSoundMeta.class);
    loadMeta(LuaSpriteMeta.class);
    loadMeta(LuaSubsystemMeta.class);
    loadMeta(LuaTextComponentMeta.class);
    loadMeta(LuaTextMeta.class);
    loadMeta(LuaTextStyleMeta.class);
    loadMeta(LuaTransformMeta.class);
    loadMeta(LuaUIComponentMeta.class);
    loadMeta(LuaUIControllerMeta.class);
    loadMeta(LuaUIObjectMeta.class);
    loadMeta(LuaWorldObjectMeta.class);
    loadMeta(new LuaWorldRoomMeta(Undertailor.getInstance()));

    log.info("Finished loading lua object metadata");
    log.info("Primary types list: ");
    Lua.PMETA
        .values()
        .forEach(
            meta -> {
              log.info(meta.getClass().getSimpleName());
            });
  }