예제 #1
0
    private async Task <Job> EnqueueAsync(JobCall call, JobStatus status, DateTime?scheduled, TimeZoneInfo?timeZone = null)
    {
        if (call == null)
        {
            throw new ArgumentNullException(nameof(call));
        }

        if (status == JobStatus.Waiting && !scheduled.HasValue)
        {
            throw new ArgumentNullException(nameof(scheduled));
        }

        (string?parameters, string?arguments) = SerializeArguments(call);

        var job = new Job
        {
            Status    = status,
            Scheduled = scheduled,
            TimeZone  = timeZone == null ? null : timeZone.ToSerializedString(),

            Type       = call.Type,
            Method     = call.Method,
            Returns    = call.Returns,
            IsStatic   = call.IsStatic,
            Parameters = parameters,
            Arguments  = arguments,
        };

        _context.Jobs.Add(job);
        await _context.SaveChangesAsync();

        return(job);
    }
예제 #2
0
    private static (string?parameters, string?arguments) SerializeArguments(JobCall call)
    {
        string?parameters = null;
        string?arguments  = null;

        if (call.Arguments != null && call.Arguments.Length > 0)
        {
            var parms = new List <string>();
            var args  = new List <string>();

            foreach (object arg in call.Arguments)
            {
                Type?type = arg.GetType();
                if (type == null || string.IsNullOrWhiteSpace(type.AssemblyQualifiedName))
                {
                    throw new Exception("Unable to resolve assembly name of argument");
                }

                parms.Add(type.AssemblyQualifiedName);
                args.Add(JsonConvert.SerializeObject(arg));
            }

            parameters = JsonConvert.SerializeObject(parms);
            arguments  = JsonConvert.SerializeObject(args);
        }

        return(parameters, arguments);
    }
예제 #3
0
    private JobDescriptor Enqueue(JobCall job, JobStatus status, DateTime?scheduled, TimeZoneInfo?timeZone = null)
    {
        if (job == null)
        {
            throw new ArgumentNullException(nameof(job));
        }

        if (status == JobStatus.Waiting && !scheduled.HasValue)
        {
            throw new ArgumentNullException(nameof(scheduled));
        }

        int jobId         = ++_idSource;
        var jobDescriptor = new JobDescriptor
        {
            Id        = jobId.ToString(),
            Status    = status,
            Scheduled = scheduled,
            TimeZone  = timeZone,
            Call      = job
        };

        lock (_syncLock)
        {
            _jobs.Add(jobDescriptor);
        }

        return(jobDescriptor);
    }
예제 #4
0
 public JobCall addJobCall(IStructure originStructure, IStructure targetStructure, Item item)
 {
     JobCall jobCall = new JobCall(originStructure, targetStructure, item, this);
     if (jobCall == null) throw new ArgumentException();
     JobCalls.Add(jobCall);
     Debug.Log("Added new Jobcall: " + jobCall.ToString());
     return jobCall;
 }
예제 #5
0
    public void Invoke(JobCall job, CancellationToken cancellationToken)
    {
        if (job.Returns != VoidTypeName)
        {
            throw new ArgumentException("Method must return void", nameof(job));
        }

        InvokeMember(job.Type, job.IsStatic, job.Method, job.Arguments);
    }
예제 #6
0
    public async Task <string> ScheduleAsync(JobCall job, DateTime scheduled, TimeZoneInfo?timeZone = null)
    {
        if (job == null)
        {
            throw new ArgumentNullException(nameof(job));
        }

        Job result = await EnqueueAsync(job, JobStatus.Waiting, scheduled, timeZone);

        return(result.Id.ToString());
    }
예제 #7
0
    public async Task <string> EnqueueAsync(JobCall job)
    {
        if (job == null)
        {
            throw new ArgumentNullException(nameof(job));
        }

        Job result = await EnqueueAsync(job, JobStatus.Ready, null);

        return(result.Id.ToString());
    }
예제 #8
0
    public Task <string> ScheduleAsync(JobCall job, DateTime scheduled, TimeZoneInfo?timeZone = null)
    {
        if (job == null)
        {
            throw new ArgumentNullException(nameof(job));
        }

        JobDescriptor jobDescriptor = Enqueue(job, JobStatus.Waiting, scheduled, timeZone);

        // Refresh the queue observer.
        _signal.Release();

        return(Task.FromResult(jobDescriptor.Id));
    }
예제 #9
0
    public Task <string> EnqueueAsync(JobCall job)
    {
        if (job == null)
        {
            throw new ArgumentNullException(nameof(job));
        }

        JobDescriptor jobDescriptor = Enqueue(job, JobStatus.Ready, null);

        _queue.Enqueue(jobDescriptor);
        _signal.Release();

        return(Task.FromResult(jobDescriptor.Id));
    }
예제 #10
0
 public async Task RunAsync(JobCall job, CancellationToken cancellationToken)
 {
     if (job.Returns == TaskTypeName)
     {
         await InvokeAsync(job, cancellationToken);
     }
     else if (job.Returns == VoidTypeName)
     {
         Invoke(job, cancellationToken);
     }
     else
     {
         throw new Exception($"Unsupported job return type '{job.Returns}'");
     }
 }
예제 #11
0
    public Task InvokeAsync(JobCall job, CancellationToken cancellationToken)
    {
        if (job.Returns != TaskTypeName)
        {
            throw new ArgumentException("Async method must return a Task", nameof(job));
        }

        object?result = InvokeMember(job.Type, job.IsStatic, job.Method, job.Arguments);

        if (result == null)
        {
            throw new Exception("Expected a task result");
        }

        return((Task)result);
    }
예제 #12
0
 public Task RecurrentAsync(string name, string cron, JobCall job, TimeZoneInfo?timeZone = null)
 {
     return(Task.CompletedTask);
 }
예제 #13
0
    public void DecideNextAction()
    {
        Debug.Log("Deciding next action");
        switch (walkerStatus)
        {
        case WalkerStatus.CollectingBlocks:
        {
            if (objectToWalk.getItemInventory().isFull())
            {
                depositBlocksInSilo();
                return;
            }

            if (targetStructure == null || targetStructure.isDestroyed())
            {
                findNextTarget();
                return;
            }

            if (isStructureCloseEnough(targetStructure))
            {
                Debug.Log("mining");
                objectToWalk.Mine();
                return;
            }
            else
            {
                Debug.Log("not close enough to mine");
            }

            break;
        }

        case WalkerStatus.InventoryCalls:
        {
            IInventory inventory = objectToWalk.getItemInventory();
            Debug.Log("Status: Inventory Call");

            if (activeJobCall == null)
            {
                JobCall jobCall = JobController.Instance.getNextJobCall();

                if (jobCall == null || jobCall.itemToBeDelivered.getAmount() == 0)
                {
                    Debug.Log("Found no Inventory calls");
                    walkerStatus    = WalkerStatus.CollectingBlocks;
                    targetStructure = null;
                    DecideNextAction();
                    return;
                }
                Debug.Log("JobCall: item amount: " + jobCall.itemToBeDelivered.getAmount());
                activeJobCall = jobCall;
                Item itemInInv = inventory.TryGetItem(jobCall.itemToBeDelivered);
                if (itemInInv == null || itemInInv.getAmount() == 0)
                {
                    SetTargetPosition(Silo.Instance, out bool success);
                }
                else
                {
                    SetTargetPosition(activeJobCall.targetStructure, out bool success);
                    if (!success)
                    {
                        targetStructure = null;
                        walkerStatus    = WalkerStatus.CollectingBlocks;
                        DecideNextAction();
                    }
                }
            }

            if (activeJobCall.itemToBeDelivered.getAmount() == 0)
            {
                activeJobCall = null;
                DecideNextAction();
                return;
            }


            Item itemInInvv = inventory.TryGetItem(activeJobCall.itemToBeDelivered);
            if (itemInInvv == null || itemInInvv.getAmount() == 0)
            {
                if (!inventory.isEmpty())
                {
                    depositBlocksInSilo();
                    return;
                }

                TakeItems();
                return;
            }

            DepositItems();
            break;
        }
        }
    }