Can $bit() create variables here? - objectscript

Code extracted from this project:
Method RefineSearch(pNewCriteria As %String) As %Status [ ZenMethod ]
{
set tSC = $$$OK
try {
set ..criteria = ..criteria _$s(..criteria="":"",1:",")_pNewCriteria
set tType = $piece(pNewCriteria,":",1)
if tType="prop" {
set tSQL = "SELECT ID FROM "_..tableName_" WHERE "_$piece(pNewCriteria,":",2)_" = '"_$piece(pNewCriteria,":",3)_"' AND %ID %FIND Demo_SearchPortal.Find("_..qid_")"
set tResult = ##class(%SQL.Statement).%ExecDirect(,tSQL)
while tResult.%Next() {
set tID = tResult.%GetData(1)
$$$IFBITOFFPOS(tID,tChunk,tPos)
set $bit(tBits(tChunk),tPos)=1 // <-- HERE
}
// compress bitmaps
set tMaxChunk=$order(tBits(""),-1)
for tChunk = 1:1:tMaxChunk {
set tBits(tChunk) = $bitlogic(tBits(tChunk))
}
} else {
set tFinder = $classmethod(..className, ..indexName_"Embedded")
if (tType = "entity") {
do tFinder.PrepareFind("{"_$piece(pNewCriteria,":",2)_"}", ..searchMode)
} elseif (tType = "word") {
do tFinder.PrepareFind($piece(pNewCriteria,":",2), ..searchMode)
}
merge tOldBits = ^CacheTemp.IF.SearchPortal.Query(..qid,"b")
set tChunk=""
for {
set tBits = tFinder.NextChunk(.tChunk)
quit:tChunk=""
set tBits(tChunk)=$bitlogic(tBits & tOldBits(tChunk))
}
}
set tNewQID = $i(^CacheTemp.IF.SearchPortal.Query)
merge ^CacheTemp.IF.SearchPortal.Query(tNewQID,"b") = tBits
set ^CacheTemp.IF.SearchPortal.Query(tNewQID, "parent") = ..qid
set ..qid = tNewQID
} catch (ex) {
set tSC = ex.AsStatus()
}
quit tSC
}
At the place marked <-- HERE, this is the first occurrence of tBits -- with a subscripted access to boot.
Is this really legal?

Yes $bit can be used as left side function in SET command, and in this case any legal variable, legal as well. And if this variable was undefined will get new value. As well as $bit also available $piece and $extract, you can see it in documentation

Related

Jetpack Compose Observe mutableStateOf in ViewModel

I have a need to update the user profile switch
ViewModel
class ProfileViewModel : BaseViewModel() {
var greet = mutableStateOf(user.pushSetting.greet)
var message = mutableStateOf(user.pushSetting.message)
var messageDetails = mutableStateOf(user.pushSetting.messageDetails)
var follow = mutableStateOf(user.pushSetting)
var like = mutableStateOf(user.pushSetting.like)
var comment = mutableStateOf(user.pushSetting.comment)
fun updateUser() {
println("--")
}
}
2.Composable
#Composable
fun SettingCard(viewModel: ProfileViewModel) {
Lists {
Section {
TextRow(text = "手机号码") { }
TextRow(text = "修改密码", line = false) { }
}
Section {
SwitchRow(text = "新好友通知", checkedState = viewModel.greet)
SwitchRow(text = "新消息通知", checkedState = viewModel.message)
SwitchRow(text = "消息显示详细", line = false, checkedState = viewModel.messageDetails)
}
}
}
3.SwitchRow
#Composable
fun SwitchRow(text: String, line: Boolean = true, checkedState: MutableState<Boolean>) {
ListItem(
text = { Text(text) },
trailing = {
Switch(
checked = checkedState.value,
onCheckedChange = { checkedState.value = it },
colors = SwitchDefaults.colors(checkedThumbColor = MaterialTheme.colors.primary)
)
}
)
}
How can I observe the change of the switch and call updateUser() in ViewModel
I know this is a way, but it is not ideal. The network update will be called every time it is initialized. Is there a better solution?
LaunchedEffect(viewModel.greet) {
viewModel.updateUser()
}
The best solution for this would be to have unidirectional flow with SwitchRow with a lambda as #Codecameo advised.
But if you want to observe a MutableState inside your Viewmodel you can use snapshotFlows as
var greet: MutableState<Boolean> = mutableStateOf(user.pushSetting.greet)
init {
snapshotFlow { greet.value }
.onEach {
updateUser()
}
.launchIn(viewModelScope)
//...
}
Create a Flow from observable Snapshot state. (e.g. state holders
returned by mutableStateOf.) snapshotFlow creates a Flow that runs
block when collected and emits the result, recording any snapshot
state that was accessed. While collection continues, if a new Snapshot
is applied that changes state accessed by block, the flow will run
block again, re-recording the snapshot state that was accessed. If the
result of block is not equal to the previous result, the flow will
emit that new result. (This behavior is similar to that of
Flow.distinctUntilChanged.) Collection will continue indefinitely
unless it is explicitly cancelled or limited by the use of other Flow
operators.
Add a callback lamba in SwitchRow and call it upon any state change
#Composable
fun SettingCard(viewModel: ProfileViewModel) {
Lists {
Section {
TextRow(text = "手机号码") { }
TextRow(text = "修改密码", line = false) { }
}
Section {
SwitchRow(text = "新好友通知", checkedState = viewModel.greet) {
viewModel.updateUser()
}
SwitchRow(text = "新消息通知", checkedState = viewModel.message) {
viewModel.updateUser()
}
SwitchRow(text = "消息显示详细", line = false, checkedState = viewModel.messageDetails) {
viewModel.updateUser()
}
}
}
}
#Composable
fun SwitchRow(
text: String,
line: Boolean = true,
checkedState: MutableState<Boolean>,
onChange: (Boolean) -> Unit
) {
ListItem(
text = { Text(text) },
trailing = {
Switch(
checked = checkedState.value,
onCheckedChange = {
onChange(it)
checkedState.value = it
},
colors = SwitchDefaults.colors(checkedThumbColor = MaterialTheme.colors.primary)
)
}
)
}
Another approach:
You can keep MutableStateFlow<T> in your viewmodel and start observing it in init method and send a value to it from SwitchRow, like viewModel.stateFlow.value = value.
Remember, MutableStateFlow will only trigger in the value changes. If you set same value twice it will discard second value and will execute for first one.
val stateFlow = MutableStateFlow<Boolean?>(null)
init {
stateFlow
.filterNotNull()
.onEach { updateUser() }
.launchIn(viewModelScope)
}
In switchRow
viewmodel.stateFlow.value = !(viewmodel.stateFlow.value?: false)
This could be one potential solution. You can implement it in your convenient way.

Getting "A local variable named X cannot be declared in this scope" error in Unity 5

I am getting this error in unity:
5.50f3
Assets/Scripts/BaseClient/client.c s(14701,12): error CS0136: A local variable named 'text' cannot be declared in this scope because it would give a different meaning to 'text', which is already used in a 'child' scope to denote something else
Here is snippet of code:
case 126:
//String text = inStream.readString();
int frame = inStream.method435();
if (text.StartsWith("www."))
{
//openURL(text);
pktType = -1; return true;
}
if(text != null && frame != null)
{
updateStrings(text, frame);
sendFrame126(text, frame);
}
if (frame >= 18144 && frame <= 18244)
{
//clanList[frame - 18144] = text;
}
pktType = -1; return true;
The error is simply letting you know that you are reusing the same name for two variables:
int myVar = 0; // this one is global to the class
void Start()
{
int myVar = 20; // local variable, same name => problem
}
other case is within statement
if(condA)
{
int myResult = MethodA();
}
else
{
int myResult = MethodB();
}
This is likely what you are facing. Either give a different name in each subsection or get the variable out:
int myResult = -1;
if(condA)
{
myResult = MethodA();
}
else
{
myResult = MethodB();
}
This is likely what you are facing. Either give a different name in each

Attribute alignment after edit in AutoCAD

I have a simple routine that updates the text value of an attributereference. After the routine runs the values are updated in the drawing but the text is left justified and not centered. I have not been able to find any command that will cause AutoCAD to update the text location. So any help would be appreciated.
My Code
using (Transaction acTrans = db.TransactionManager.StartTransaction())
{
BlockTable bt = (BlockTable)acTrans.GetObject(db.BlockTableId, OpenMode.ForRead);
foreach (ObjectId oid in bt)
{
BlockTableRecord btr = (BlockTableRecord)acTrans.GetObject(oid, OpenMode.ForRead);
foreach (ObjectId o in btr)
{
if (o.ObjectClass.Name == "AcDbBlockReference")
{
BlockReference br = (BlockReference)acTrans.GetObject(o, OpenMode.ForRead);
BlockTableRecord b2 = (BlockTableRecord)acTrans.GetObject(br.BlockTableRecord, OpenMode.ForRead);
if (b2.Name == blockName)
{
AttributeCollection ac = br.AttributeCollection;
foreach (ObjectId i in ac)
{
AttributeReference ar = (AttributeReference)acTrans.GetObject(i, OpenMode.ForWrite);
string tagName = ar.Tag;
foreach (TestAutoCADCntrl.CBAttributeTag t in tags)
{
if (t.TagName == tagName)
{
ar.Justify = AttachmentPoint.MiddleCenter;
ar.AdjustAlignment(db);
ar.TextString = t.TagValue;
ar.DowngradeOpen();
}
}
}
br.RecordGraphicsModified(true);
}
}
}
}
acTrans.Commit();
Sorry, I have been searching for this issue for 3 days and found the answer right after i posted this question. For anyone else you just need to change the working database before you update the attribute text value.
foreach (TestAutoCADCntrl.CBAttributeTag t in tags)
{
if (t.TagName == tagName)
{
Database wdb = HostApplicationServices.WorkingDatabase; HostApplicationServices.WorkingDatabase = db;
ar.TextString = t.TagValue;
ar.AdjustAlignment(db);
HostApplicationServices.WorkingDatabase = wdb;
}
}

Different syntax highlighting for sub-types of comments (?)

I'm working in TextMate2, but this question may apply to other text editors as well.
My script is in R. I intend to use rmarkdown::render() on the script to create a "report".
The clever part of these reports is that they distinguish between the standard comment symbol in R (#), and the following:
#' indicates markdown, like in roxygen,
#+ indicates that a knitr code chunk will follow
I suck at editing TextMate2 bundles. I managed to get hotkeys set up to comment out lines with #' and #+, and to do it with proper indentation. Now, I wish I could edit my theme (which I designed in TextMate1) to make one of those "special" comments a different color.
I've edited the R bundle's language grammar (this is how the file starts):
{ patterns = (
{ name = 'comment.line.pragma-mark.r';
match = '^(#pragma[ \t]+mark)[ \t](.*)';
captures = {
1 = { name = 'comment.line.pragma.r'; };
2 = { name = 'entity.name.pragma.name.r'; };
};
},
{ begin = '(^[ \t]+)?(?=#)';
end = '(?!\G)';
beginCaptures = { 1 = { name = 'punctuation.whitespace.comment.leading.r'; }; };
patterns = (
{ name = 'comment.line.number-sign.r';
begin = '#';
end = '\n';
beginCaptures = { 0 = { name = 'punctuation.definition.comment.r'; }; };
},
);
},
And inserted the following into the middle, hoping it would let me specify a new scope for syntax highlighting:
# START MY STUFF
{ begin = '(^[ \t]+)?(?=#'')';
end = '(?!\G)';
beginCaptures = { 1 = { name = 'punctuation.whitespace.comment.leading.r'; }; };
patterns = (
{ name = 'comment.line.number-sign-tick.r';
begin = "#'";
end = '\n';
beginCaptures = { 0 = { name = 'punctuation.definition.comment.r'; }; };
},
);
},
# END MY STUFF
If it would help, I could provide the rest of the language grammar, but I'm not sure it's relevant here.
I tried to be more specific when redefining the comment in the theme (previous was just comment, which I changed to comment.line.number-sign.r). Here are (what I think are) the relevant lines of the theme:
{ name = 'Comment';
scope = 'comment.line.number-sign.r';
settings = {
fontStyle = 'italic';
foreground = '#279797';
};
},
{ name = 'Comment';
scope = 'comment.line.number-sign-tick.r';
settings = {
fontStyle = 'italic';
foreground = '#C5060B';
};
},
So far, I cannot achieve any difference in the syntax highlighting of a line that starts with # versus a line that starts with #'. I can get both to change, but no independently. Any help in figuring out how to achieve different syntax highlighting for those two would be great.
TextMate is preferring the first scope, comment.line.number-sign.r to your custom grammars. All I did is paste your code above my comment.line.number-sign.r definition, instead of after as you had indicated, and expanded upon your existing grammar/theme.
Here's what I've got:
In Bundle Editor-> R -> Language Grammars -> R
{ patterns = (
//default block
{ name = 'comment.line.pragma-mark.r';
match = '^(#pragma[ \t]+mark)[ \t](.*)';
captures = {
1 = { name = 'comment.line.pragma.r'; };
2 = { name = 'entity.name.pragma.name.r'; };
};
},
//your block
{ begin = '(^[ \t]+)?(?=#'')';
end = '(?!\G)';
beginCaptures = { 1 = { name = 'punctuation.whitespace.comment.leading.r'; }; };
patterns = (
{ name = 'comment.line.number-sign-tick.r';
begin = "#'";
end = '\n';
beginCaptures = { 0 = { name = 'punctuation.definition.comment.r'; }; };
},
);
},
//my block
{ begin = '(^[ \t]+)?(?=#\+)';
end = '(?!\G)';
beginCaptures = { 1 = { name = 'punctuation.whitespace.comment.leading.r'; }; };
patterns = (
{ name = 'comment.line.number-sign-plus.r';
begin = '#\+';
end = '\n';
beginCaptures = { 0 = { name = 'punctuation.definition.comment.r'; }; };
},
);
},
//default caption block
{ begin = '(^[ \t]+)?(?=#)';
end = '(?!\G)';
beginCaptures = { 1 = { name = 'punctuation.whitespace.comment.leading.r'; }; };
patterns = (
{ name = 'comment.line.number-sign.r';
begin = '#';
end = '\n';
beginCaptures = { 0 = { name = 'punctuation.definition.comment.r'; }; };
},
);
},
//...
And then, in my theme:
//...
{ name = 'Comment';
scope = 'comment.line.number-sign.r';
settings = {
fontStyle = 'italic';
foreground = '#279797';
};
},
{ name = 'Comment';
scope = 'comment.line.number-sign-tick.r';
settings = {
fontStyle = 'italic';
foreground = '#C5060B';
};
},
{ name = 'Comment';
scope = 'comment.line.number-sign-plus.r';
settings = {
fontStyle = 'italic';
foreground = '#ff00ff';//fix this color(!)
};
},
);
}
I don't use R, so I just Googled for a quick example with all 3 kinds of comments. Here's the file I used to test.
A screenshot of what I'm seeing:

C# console App compare records to database

I am parsing a flat file which is working line by line and inserting into the database but I want to add an additional step, actually additional 2 steps.
First I only want records for recalls for specific car manufacturers which I have a database table called AutoMake that has a list of all the makes I want to include. I need to compare the record to that table to ensure that it is a record of one of the makes that I want to include.
Then I need to do a second check to make sure the record is not already in my database.
This is a console App and I am using Entity for this. So here is my code I am driving myself crazy trying to write and rewrite this to include the checks but im just not getting it.
Oh and not that it really matters because if someone can get me in the right direction I can move from there but tokens[2] is the MAKETXT and RCL_CMPT_ID is tokens[23] and RCL_CMPT_ID can be used to verify if a record is already in the database since it is a unique value
public static void ParseTSV(string location)
{
Console.WriteLine("Parsing.....");
using (var reader = new StreamReader(location))
{
var lines = reader.ReadToEnd().Split(new char[] { '\n' });
if (lines.Length > 0)
{
foreach (string line in lines)
{
if (string.IsNullOrWhiteSpace(line))
{
continue;
}
var tokens = line.Trim().Split(new char[] { '\t' });
var recalls = new Recalls();
recalls.RECORD_ID = tokens[0];
recalls.CAMPNO = tokens[1];
recalls.MAKETXT = tokens[2];
recalls.MODELTXT = tokens[3];
recalls.YEARTXT = tokens[4];
recalls.MFGCAMPNO = tokens[5];
recalls.COMPNAME = tokens[6];
recalls.MFGNAME = tokens[7];
recalls.BGMAN = tokens[8];
recalls.ENDMAN = tokens[9];
recalls.RCLTYPECD = tokens[10];
recalls.POTAFF = tokens[11];
recalls.ODATE = tokens[12];
recalls.INFLUENCED_BY = tokens[13];
recalls.MFGTXT = tokens[14];
recalls.RCDATE = tokens[15];
recalls.DATEA = tokens[16];
recalls.RPNO = tokens[17];
recalls.FMVSS = tokens[18];
recalls.DESC_DEFECT = tokens[19];
recalls.CONEQUENCE_DEFECT = tokens[20];
recalls.CORRECTIVE_ACTION = tokens[21];
recalls.NOTES = tokens[22];
recalls.RCL_CMPT_ID = tokens[23];
string connectionString = GetConnectionString();
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand cmdIns = new SqlCommand(GetInsertSqlCust(recalls), connection);
connection.Open();
cmdIns.ExecuteNonQuery();
connection.Close();
cmdIns.Dispose();
cmdIns = null;
}
}
}
}
}
1:Get the ID to check against
2:Get the table where the search needs to be done like
string strExpression="";
(Datatable tdGeneric = dal.getsometable())
3:To check the auto make if exists:
if ( tdGeneric != null && tdGeneric.Rows.Count > 0)
{
strExpression = "tablecolumnsname = '" + recalls.MAKETXT + "' ";
tdGeneric.DefaultView.RowFilter = strExpression;
tdGeneric = tdGeneric.DefaultView.ToTable();
if (tdGeneric.Rows.Count > 0)
{
//make exist
}
else
make don't exists
}
else
{
make don't exist skip that text file's record
}
4: if make exist then check for a record if that exists in a table.
get the original table,search on that table for specific id in your case:
(Datatable tdGeneric2 = dal.getsometable())
if ( tdGeneric2 != null && tdGeneric.Rows.Count > 0)
{
strExpression = "tablecolumnsname = '" + recalls.RCL_CMPT_ID + "' ";
tdGeneric2.DefaultView.RowFilter = strExpression;
tdGeneric2 = tdGeneric2.DefaultView.ToTable();
if (tdGeneric2.Rows.Count > 0)
{
//record exist
}
else
record don't exists
}
else
{
record don't exist insert the record, or some flag to insert a record
}
You can take advantages of caching. Fetch all the Makes before reading the file and do a lookup in the List or Dictionary of existing AutoMakes to check if the AutoMake already exists in database or it is a new one. If the AutoMake is new, insert the record in database and also add the make in List\Dictionary. If AutoMake already exists, skip the line and move to next line.

Resources