|
|
|
Supreme Being
      
Group: Forum Members
Last Login: 2009-12-21 19:09:25
Posts: 111,
Visits: 839
|
|
Hi everyone,
I modeled two classes that were like these: TRequisito 0..* 0..* TOrdemServico.
TOrdemServico has a State attributte that is a Enum.
I want to have a derived attributte on Requisite that depends on the State Attributte of all ServiceOrders associated to it. Can it be done?
I tried something like this:
function TRequisito.EstadoDeriveAndSubscribe(reevaluateSubscriber: Eco.Subscription.ISubscriber;
resubscribeSubscriber: Eco.Subscription.ISubscriber): System.Object;
var
OclService: IOclService;
Estados: IList;
begin
AsIObject.Properties.GetByLoopbackIndex(Eco_LoopbackIndices.Ordens).SubscribeToValue(reevaluateSubscriber);
OclService := AsIObject.ServiceProvider.GetEcoService();
Estados := OclService.Evaluate(AsIObject, 'self.Ordens.Estado->asSet').GetAsIList;
if (Estados.Count = 1) then
if Estados.Contains(EstadoServico.Concluida) then
Result := Enum(EstadoServico.Concluida).ToString
else //Pendente
Result := Enum(EstadoServico.Pendente).ToString
else
Result := Enum(EstadoServico.Execucao).ToString
end;
--
Pedro Brown
pedro@tectrilha.com.br
Tectrilha Software - Borland Learning Partner
|
|
|
|
|
Forum Newbie
      
Group: Forum Members
Last Login: 2010-01-12 10:44:52
Posts: 8,
Visits: 25
|
|
| Hi Pedro, When evaluating the set of state attributes you should also subscribe to it: function TRequisito.EstadoDeriveAndSubscribe(reevaluateSubscriber: Eco.Subscription.ISubscriber; resubscribeSubscriber: Eco.Subscription.ISubscriber): System.Object; var OclService: IOclService; Estados: IList; begin OclService := AsIObject.ServiceProvider.GetEcoService(); Estados := OclService.EvaluateAndSubscribe(AsIObject, 'self.Ordens.Estado->asSet', reevaluateSubscriber, resubscribeSubscriber).GetAsIList; if (Estados.Count = 1) then ... end; But why won't you achieve the same using OCL derivation? Regards, -- Oleg Zhukov
--
Oleg Zhukov
|
|
|
|
|
Supreme Being
      
Group: Administrators
Last Login: 2010-11-30 12:17:13
Posts: 1 230,
Visits: 1 382
|
|
Hi Pedro
First of all, if you change your signature to
function TRequisito.EstadoDerive(): System.Object;
you can skip the subscriptions, ECO will automatically subscribe to anything you read from the cache.
Second, I don't think using OCL in this case makes things any easier. Without OCL your code would look somehting like:
if (self.Ordens.Count = 1) then
if self.Ordens[0].Estado = EstadoServico.Concluida then
Result := Enum(EstadoServico.Concluida).ToString
else //Pendente
Result := Enum(EstadoServico.Pendente).ToString
else
Result := Enum(EstadoServico.Execucao).ToString
end;
as far as I see, this code is equivalent to the one you wrote, I'm not sure exactly what you are trying to achieve. perhaps if you explain in plain words what the calculation is supposed yield there are easier ways to code it...
/Jonas Hogstrom [CapableObjects]
|
|
|
|
|
Forum Newbie
      
Group: Forum Members
Last Login: 2010-01-12 10:44:52
Posts: 8,
Visits: 25
|
|
Indeed, the variant with an automaic subscription suggested by Jonas looks most attractive. I just haven't got used to the automatic subscribtions feature  Thanks,
--
Oleg Zhukov
|
|
|
|
|
Supreme Being
      
Group: Forum Members
Last Login: 2009-12-21 19:09:25
Posts: 111,
Visits: 839
|
|
Hi Jonas,
Thanks for your reply. I didn't understand why should I change the method signature? ECO generated it automatically for me. I also didn't understand the automatic subscription. Could you explain it a litlle bit further to me?
You asked me to explain what I want to achieve with this code. What I want is:
TOrderServico has a State Machine linked to it.
A TRequisito has a list of TOrdemServico. TRequisito has a calculated State attribute (not linked to a State Machine) that depends on the State of the TOrdemServico in that list.
If I change the state of a TOrdemServico, I'd like to recalculate the state of TRequisito.
The calculation involves these steps:
I retrieve a list containing a set of States in TRequisito's list of TOrdemServico. After that I match some conditions to determine witch state is TRequisito.
Thanks.
--
Pedro Brown
pedro@tectrilha.com.br
Tectrilha Software - Borland Learning Partner
|
|
|
|
|
Supreme Being
      
Group: Administrators
Last Login: 2010-11-30 12:17:13
Posts: 1 230,
Visits: 1 382
|
|
the codegeneration in RadStudio will generate a XXXDeriveAndSubscribe method, but if you change it to just XXXDerive (with no parameters), it will not regerenate the DeriveAndSubscribe method again.
The automatic subscription is a bit of ECO magic. When you implement a derived attribute, it is important that anything you read gets subscribed to. If you implement XXXDeriveAndSubscribe, you will be responsible for performing all the subscriptions yourself, but if the signature is XXXDerive, ECO will automatically subscribe to anything you read from the cache. In your case, you had actually missed one subscription, the one on the state-attribute, you had only subscribed to the multilink. The automatic subscription will subscribe to everything you read using the "ReSubscribe subscriber". It will in some cases give a little less performance since ECO will have to resubscribe to your expression regardless of the changes, but in most cases this can be ignored. If you need to subscribe to something outside of the ECO cache, you still need to place those subscriptions manually (in this case you need to implement the XXXDeriveAndSubscribe).
Actually, I noticed that your original code contained another error... You used the reEvaluateSubscriber in your subscription, but you should have used the reSubscribeSubscriber since it was a multilink and you wanted to look at the elements.
We know that understanding the inner workings of subscriptions is pretty hard, and this is the reason we implemented the autosubscribe feature so you don't need to worry about the details.
Autosubscriptions is available in ECO 4.0.0.1963 and later. If you have a version earlier than that I strongly suggest you update.
/Jonas Hogstrom [CapableObjects]
|
|
|
|
|
Supreme Being
      
Group: Forum Members
Last Login: 2009-12-21 19:09:25
Posts: 111,
Visits: 839
|
|
Hi Jonas,
I'd like to know if I can continue to use "Estados := OclService.Evaluate(AsIObject, 'self.Ordens.Estado->asSet').GetAsIList < String > " in my code. Note thar self is a TRequisito, self.Ordens is a Collection(TOrdemServico) and self.Ordens.Estado is a Collection(String).
Thanks
--
Pedro Brown
pedro@tectrilha.com.br
Tectrilha Software - Borland Learning Partner
|
|
|
|
|
Supreme Being
      
Group: Administrators
Last Login: 2010-11-30 12:17:13
Posts: 1 230,
Visits: 1 382
|
|
I think it is possible to use ocl-evaluations inside an autosubscribed region (without breaking the autosubscription mechanism), but I don't think that using an ocl-expression in this case makes the code any easier to understand.
If you just loop over the related objects (TOrdemServico) and check their state attribute and do your calculation in code, I think it will result in clearer code.
/Jonas Hogstrom [CapableObjects]
|
|
|
|
|
Forum Member
      
Group: Forum Members
Last Login: 2009-12-11 17:29:47
Posts: 27,
Visits: 281
|
|
| Yes, it is possible to use the OCL-service when using autosubscxriptions.
|
|
|
|