package com.lzh.baselib;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
/**
* 构造时如果传入了任务返回结果的类型,则运行会自动尝试构造不带参数的结果实例,并保存
* 界面解析任务
* 支持外部逻辑注入
* 支持id标记
* task处理结果保存在DataPackage中,键值为taskId
* task 生命周期结束后需要统一销毁
* 闲散的task id标号从1000开始
*/
public abstract class BaseTask implements ITask, IBaseIdItem {
private static final IdAllocator mIdAllocator = new IdAllocator(IdAllocator.AllocateType.TYPE_SCATTERED_TASK, 100);
private static final String TAG = "BaseTask";
private int mTaskId = -1;
private String mTaskDesc = "";
protected List<BaseTask> preTasks = new ArrayList<>();
protected List<BaseTask> postTasks = new ArrayList<>();
private Object mLock = new Object();
private BaseTask mOwner = null;
private LLMResult mTempResult = null;
private boolean mIsVisibleToSameOwner = false;
/**
* 创建分散的Task,****注意及时手动释放****
*
* @param preTask
* @param postTask
*/
public BaseTask(BaseTask preTask, BaseTask postTask) {
preTasks.add(preTask);
postTasks.add(postTask);
}
/**
* 构造BaseTask实例,给每个Task分配一个Id
*/
public BaseTask() {
try {
mTaskId = mIdAllocator.allocate();
} catch (Exception e) {
CVLog.e(TAG, "id exceeds max num:" + mIdAllocator.getMaxID());
mIdAllocator.reset();
try {
mTaskId = mIdAllocator.allocate();
} catch (Exception ex) {
CVLog.e(TAG, "id exceeds max num:" + mIdAllocator.getMaxID());
}
}
CVLog.d(TAG, "create Task id =" + mTaskId + " Task class:" + getTaskDesc());
}
public void readTaskParams(Package paramsPackage) throws NoSuchFieldException, IllegalAccessException {
ParamKey[] annotations = this.getClass().getAnnotationsByType(ParamKey.class);
for (ParamKey annotation : annotations) {
Field field = this.getClass().getDeclaredField(annotation.name());
field.set(this, paramsPackage.get(annotation.name(), field.getType()));
}
}
public BaseTask setOwner(BaseTask owner) {
mOwner = owner;
return this;
}
public BaseTask getOwner() {
return mOwner;
}
@Override
public Object run(Package params) {
CVLog.i(TAG, getTaskDesc() + " task start run. task id=" + mTaskId + " pre.size =" + preTasks.size() + " post.size =" + postTasks.size());
try {
readTaskParams(params);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}catch (NoSuchFieldException e) {
CVLog.e(TAG, "readTaskParams error!", e);
}
return null;
}
public void setTaskDesc(String taskDesc) {
mTaskDesc = taskDesc;
}
@Override
public String getTaskDesc() {
if (mTaskDesc.isEmpty()) {
if (getOwner() != null) {
return getOwner().getClass().getSimpleName() + "/" + getId() + "_" + getClass().getSimpleName();
}
return getId() + "_" + getClass().getName();
}
return mTaskDesc;
}
public void setPreProcess(List<BaseTask> tasks) {
preTasks = tasks;
for(BaseTask task : tasks){
task.setOwner(this);
}
}
public BaseTask addPre(BaseTask task) {
preTasks.add(task);
task.setOwner(this);
return this;
}
/**
* 向前处理列表中插入任务,原任务后移
* @param index 负数表示倒数第index位,如-2表示插入倒数第2位
* @param task
* @return
*/
public BaseTask insertPre(int index, BaseTask task) {
if(index < 0){
index = preTasks.size() + index + 1;
}
if(index < 0){
index = 0;
CVLog.i(TAG, "index < 0, will add at 0 ");
}
if(index > postTasks.size()){
index = postTasks.size();
CVLog.i(TAG, "index < 0, will add at " + postTasks.size());
}
preTasks.add(index, task);
task.setOwner(this);
return this;
}
public BaseTask setPostProcess(List<BaseTask> tasks) {
postTasks = tasks;
for(BaseTask task : tasks){
task.setOwner(this);
}
return this;
}
public BaseTask addPost(BaseTask task) {
postTasks.add(task);
task.setOwner(this);
return this;
}
/**
* 向前处理列表中插入任务,原任务后移
* @param index 负数表示倒数第index位,如-2表示插入倒数第2位
* @param task
* @return
*/
public BaseTask insertPost(int index, BaseTask task) {
if(index < 0){
index = postTasks.size() + index + 1;
CVLog.i(TAG, "after transform, index = " + index);
}
if(index < 0){
index = 0;
CVLog.i(TAG, "index < 0, will add at 0 ");
}
if(index > postTasks.size()){
index = postTasks.size();
CVLog.i(TAG, "index < 0, will add at " + postTasks.size());
}
postTasks.add(index, task);
task.setOwner(this);
return this;
}
public void updatePre(Class<?> oldTaskType, BaseTask newTask) {
for (int i = 0; i < preTasks.size(); i++) {
if (preTasks.get(i).getClass().equals(oldTaskType)) {
CVLog.d(TAG, "update pre task:" + preTasks.get(i).getTaskDesc() + "to" + newTask.getTaskDesc());
preTasks.get(i).release();
preTasks.set(i, newTask);
newTask.setOwner(this);
}
}
}
public void updatePost(Class<?> oldTaskType, BaseTask newTask) {
for (int i = 0; i < postTasks.size(); i++) {
if (postTasks.get(i).getClass().equals(oldTaskType)) {
postTasks.get(i).release();
CVLog.d(TAG, "update post task:" + newTask.getTaskDesc());
postTasks.set(i, newTask);
newTask.setOwner(this);
}
}
}
@Override
public int getTaskState() {
return 0;
}
@Override
public void release() {
CVLog.i(TAG, "release task:" + mTaskId + " taskClass: " + this.getClass().getName());
synchronized (mLock) {
for (BaseTask task : preTasks) {
task.release();
}
for (BaseTask task : postTasks) {
task.release();
}
Environment.getInstance().remove(getId());
}
}
public void sendTo(BaseTask taskOwner, Package<String> messages) {
CVLog.d(TAG, "send to :" + taskOwner.getTaskDesc());
taskOwner.run(messages);
}
public void receiveFrom(BaseTask taskOwner, Package<String> messages) {
CVLog.d(TAG, "receive from :" + taskOwner.getTaskDesc());
}
@Override
public void setId(int id) {
mTaskId = id;
}
@Override
public int getId() {
return mTaskId;
}
@Override
public void destroy() {
CVLog.i(TAG, "destroy task:" + mTaskId + " taskClass: " + this.getClass().getName());
release();
preTasks.clear();
postTasks.clear();
}
public <T> T extractFromEnv(Class<T> resultClazz) {
return Environment.extract(getId(), resultClazz);
}
public <T> ArrayList<T> extractListFromEnv(Class<T> resultClazz) {
return Environment.extractList(getId(), resultClazz);
}
public void syncToEnv(Object result){
Environment.append(getId(), result);
}
/**
* 递归添加子任务结果暂存到父任务中,保持子任务缓存结果对父级任务可见
* @param key 子任务结果保存key值
* @param result 子任务结果
*/
public void addSubResult(String key, Object result){
if(mTempResult == null ){
mTempResult = new LLMResult();
}
mTempResult.put(key, result);
if(mOwner != null){
mOwner.addSubResult(key, result);
}
}
public Object retrieveCache(String key){
if(mTempResult != null ){
Object res = mTempResult.get(key);
if(res!=null){
return res;
}else if(isVisibleToSameOwner() && mOwner != null){
return mOwner.retrieveCache(key);
}
}
return null;
}
public <T> T retrieveCache(String key, Class<T> targetClazz){
if(mTempResult != null ){
T res = mTempResult.get(key, targetClazz);
if(res!=null){
return res;
}else if(isVisibleToSameOwner() && mOwner != null){
return mOwner.retrieveCache(key, targetClazz);
}
}
return null;
}
/**
* (慎用)默认key值位result的类名,仅适用于添加自定义
* @param result
*/
public void appendCache(Object result){
if(mTempResult == null ){
mTempResult = new LLMResult();
}
CVLog.i("lzhDebug", "appendCache :" + result.getClass().getSimpleName());
mTempResult.put(result.getClass().getSimpleName(), result);
if(mOwner != null){
mOwner.addSubResult(result.getClass().getSimpleName(), result);
}
}
/**
* 从任务结果中获取子任务结果, 默认key值为结果类名
* @param targetClazz
*/
public <T> T retrieveCache(Class<T> targetClazz){
if(mTempResult != null ){
T res = mTempResult.get(targetClazz.getSimpleName(), targetClazz);
if(res!=null){
return res;
}else if(isVisibleToSameOwner() && mOwner!=null){
CVLog.i("lzhDebug", "retrieveCache in current task null:" + targetClazz.getSimpleName());
return mOwner.retrieveCache(targetClazz);
}
}
CVLog.i(TAG, "retrieveCache null:" + targetClazz.getSimpleName());
return null;
}
public <T> ArrayList<T> retrieveCacheAsList(Class<T> targetClazz){
if(mTempResult != null ){
ArrayList<T> res = mTempResult.getArrayList(targetClazz.getSimpleName(), targetClazz);
if(res!=null){
return res;
}else if(isVisibleToSameOwner() && mOwner != null){
return mOwner.retrieveCacheAsList(targetClazz);
}
}
return null;
}
public <T> T[] retrieveCacheAsArray(Class<T> targetClazz){
if(mTempResult != null ){
T[] res = mTempResult.getArrays(targetClazz.getSimpleName(), targetClazz);
if(res!=null){
return res;
}else if(isVisibleToSameOwner() && mOwner != null){
return mOwner.retrieveCacheAsArray(targetClazz);
}
}
return null;
}
public boolean isVisibleToSameOwner() {
return mIsVisibleToSameOwner;
}
public void setVisibleToSameOwner(boolean visibleToSameOwner) {
mIsVisibleToSameOwner = visibleToSameOwner;
}
}
Android - 任务封装
最新推荐文章于 2024-08-25 21:30:48 发布