Package com.artemis.weaver

Source Code of com.artemis.weaver.ComponentTypeTransmuter

package com.artemis.weaver;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;

import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

import com.artemis.ClassUtil;
import com.artemis.meta.ClassMetadata;
import com.artemis.meta.FieldDescriptor;
import com.artemis.weaver.packed.PackedComponentWeaver;
import com.artemis.weaver.packed.PackedStubs;
import com.artemis.weaver.pooled.PooledComponentWeaver;

public class ComponentTypeTransmuter extends CallableTransmuter<Void> implements Opcodes {
  private ClassMetadata meta;
  private ClassReader cr;
  private ClassWriter cw;
 
  public ComponentTypeTransmuter(String file, ClassReader cr, ClassMetadata meta) {
    super(file);
    this.cr = cr;
    this.meta = meta;
  }
 
  @Override
  protected Void process(String file) throws FileNotFoundException, IOException {
    cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
    ClassVisitor cv = cw;
   
    switch (meta.annotation) {
      case PACKED:
        validateOnlyPrimitives(meta.fields);
        cr = new AccessorGenerator(cr, meta).transform();
        cr = new PackedStubs(cr, meta).transform();
        cv = new CommonClassWeaver(cv, meta);
        cv = new PackedComponentWeaver(cv, meta);
        break;
      case POOLED:
        if (!meta.foundReset) {
          injectMethodStub("reset", "()V");
          cr.accept(cw, 0);
          cr = new ClassReader(cw.toByteArray());
          cv = cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
        }
        cv = new CommonClassWeaver(cv, meta);
        cv = new PooledComponentWeaver(cv, meta);
        break;
      case NONE:
        return null;
      default:
        throw new IllegalArgumentException("Missing case: " + meta.annotation);
    }
   
    try {
      cr.accept(cv, ClassReader.EXPAND_FRAMES);
      if (file != null) ClassUtil.writeClass(cw, file);
    } catch (Exception e) {
      e.printStackTrace();
    }
   
    return null;
  }

  public ClassWriter getClassWriter() {
    return cw;
  }
 
  private void injectMethodStub(String name, String description) {
    MethodVisitor method = cw.visitMethod(ACC_PUBLIC, name, description, null, null);
    method.visitCode();
    method.visitLabel(new Label());
    method.visitInsn(RETURN);
    method.visitEnd();
  }
 
  private void validateOnlyPrimitives(List<FieldDescriptor> fields) {
    for (FieldDescriptor fd : fields) {
      if (fd.desc.length() > 1) {
        String error = String.format("%s: @PackedWeaver only works with primitive fields: %s",
          meta.type, fd);
        throw new WeaverException(error);
      }
    }
  }
}
TOP

Related Classes of com.artemis.weaver.ComponentTypeTransmuter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.